Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check xlsx-renderer browser support #93

Open
1 of 2 tasks
Siemienik opened this issue Apr 14, 2020 · 37 comments
Open
1 of 2 tasks

Check xlsx-renderer browser support #93

Siemienik opened this issue Apr 14, 2020 · 37 comments
Labels
accepted It is accepted to do important Do it first

Comments

@Siemienik
Copy link
Owner

Siemienik commented Apr 14, 2020

Working code provided here: #93 (comment)

TODO:

@watanabethais

This comment has been minimized.

@Siemienik

This comment has been minimized.

@watanabethais

This comment has been minimized.

@Siemienik

This comment has been minimized.

@Siemienik

This comment has been minimized.

@watanabethais

This comment has been minimized.

@Siemienik

This comment has been minimized.

@Siemienik

This comment has been minimized.

@Siemienik Siemienik transferred this issue from Siemienik/xlsx-renderer Nov 19, 2020
@Siemienik Siemienik added accepted It is accepted to do important Do it first labels Nov 19, 2020
@watanabethais

This comment has been minimized.

@Siemienik

This comment has been minimized.

@Siemienik Siemienik changed the title Check browser support Check xlsx-renderer browser support Nov 24, 2020
@jacekkoziol

This comment has been minimized.

@Siemienik

This comment has been minimized.

@jacekkoziol

This comment has been minimized.

@Siemienik
Copy link
Owner Author

@jacekkoziol I have good information for you. I found the reason why it failed.
XLSX renderer needs an argument called templateFactory, which returns Promise<Workbook>.
In your code, this argument is an arrow function that returns a const wrapped inside Promise.resolve().
That makes that the renderer edits output, and it is the same object as the template. As a result, it makes total crazy things 😄.

Moving loading file logic into a function resolves that problem. I've created PR into your code: https://github.com/jacekkoziol/xlsx/pull/1/files#diff-a2a171449d862fe29692ce031981047d7ab755ae7f84c707aef80701b3ea0c80R94-R97 .

Additionally, notes/tips for you.

  • The Renderer is stateless. It was designed to be a service possible to inject into Constructor (inversion of control). So I recommend to pass it into GenerateXLSXFile through the constructor or create it in a constructor (when you want to create a wrapper for it).
  • If any problems have you with the renderer, You may pass the CellTemplateDebugPool into Renderer constructor, which makes it log information about what it is doing.

I am delighted that you asked me about this. It allowed me to find some possible improvements that I want to do for xlsx-renderer 😄 Thank you. I made some notes in the code with todo @siemienik, please just ignore these.

Additionally, your code proves that the lib works in a browser, that I am really thank you for doing that :)

Information for others, that is what I changed in a code:

    const workbook: Excel.Workbook = new Excel.Workbook();
    await workbook.xlsx.load(reader.result);
    const result: Excel.Workbook = await renderer.render(() => Promise.resolve(workbook), this.viewModel);

into:

      const templateFileBuffer = reader.result;

      const templateFactory = () => { // All this logic must be provided into xlsx-renderer as a function
        const workbook: Excel.Workbook = new Excel.Workbook();
        return workbook.xlsx.load(templateFileBuffer);
      };

      const result: Excel.Workbook = await this.renderer.render(templateFactory, this.viewModel);

@jacekkoziol
Copy link
Contributor

@Siemienik Thank you for the answer, code update and tips. I have test it and it work... but only for the first time. Probably still there is something wrong with my code, but I can't find out what is causing the problem.
When I export the file, for the first time it's generated correctly, however the second and subsequent times it's not generating properly - the page needs to be reloaded and then the first file generation goes smoothly.

@Siemienik

This comment has been minimized.

@jacekkoziol
Copy link
Contributor

Thank you @Siemienik , it works perfectly 👍 The xlsx-renderer is great! :)

@Siemienik

This comment has been minimized.

@Siemienik

This comment has been minimized.

@Siemienik

This comment has been minimized.

@sumanth-basetty

This comment has been minimized.

@jacekkoziol

This comment has been minimized.

@sumanth-basetty

This comment has been minimized.

@jacekkoziol

This comment has been minimized.

@Siemienik

This comment has been minimized.

@sumanth-basetty

This comment has been minimized.

@sumanth-basetty

This comment has been minimized.

@Siemienik

This comment has been minimized.

@sumanth-basetty
Copy link

@Siemienik got it, now i get the flow how to use those generics, works fine now 😃, thank you 👍

@sumanth-basetty

This comment has been minimized.

@Siemienik

This comment has been minimized.

@Siemienik
Copy link
Owner Author

Siemienik commented Mar 13, 2021

Here I update the code to make it simpler and shorter:

import { Renderer } from "xlsx-renderer";
import { saveAs } from "file-saver";

// ... define viewModel:
const viewModel = {}; 

//... generate a report:

// 1. Download a template.
fetch("./template.xlsx")
  // 2. Get template as ArrayBuffer.
  .then((response) => response.arrayBuffer())
  // 3. Fill the template with data (generate a report).
  .then((buffer) => new Renderer().renderFromArrayBuffer(buffer, viewModel))
  // 4. Get a report as buffer.
  .then((report) => report.xlsx.writeBuffer())
  // 5. Use `saveAs` to download on browser site.
  .then((buffer) => saveAs(new Blob([buffer]), `${Date.now()}_report.xlsx`))
  // Handle errors.
  .catch((err) => console.log("Error writing excel export", err));

Sandbox: https://codesandbox.io/s/xlsx-renderer-check-forked-xp91b?file=/src/App.js:233-836

@justice-sh
Copy link

Hello,

I've ran this code and on my system, this is the error I got:

Error: Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html

And no, it's not a zip file. I get this error when I ran it with React, but with NodeJs, I don't get this error.

@jacekkoziol
Copy link
Contributor

@Sherlock-HolmesJM Probably the paths to the xlsx template file is wrong.

@Siemienik
Copy link
Owner Author

Hi, @Sherlock-HolmesJM did you resolve this problem?

@justice-sh
Copy link

Hi, @Sherlock-HolmesJM did you resolve this problem?

I did by setting up a REST API to serve my template xlsx file as a buffer

Then fetch at the frontend and worked with it.

Thank you.

@Siemienik
Copy link
Owner Author

@Sherlock-HolmesJM Thank you for confirmation, nice to read that ;)

If any help needed, you may find us on Gitter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted It is accepted to do important Do it first
Projects
Status: Important
Development

No branches or pull requests

5 participants