How to save a .docx file in react js

332 views Asked by At

I have a firebase function that creates a word document from a template and sending it back to the client, The client is getting the buffer being sent and suppose to download it to the user as a word document.

I used console.log() to print the buffer and the data is sent to the client correctly.

But for some reason I am getting this error message when trying to open it.

enter image description here

firebase function called by the user:

exports.test = functions.https.onRequest((req, res) => {
  cors(req, res, async () => {
    const parameters = req.body.data;
    const analyzer = new Analyzer(parameters);
    analyzer.analyze();
    const docxwritter = new DocxWritter(analyzer);
    const buffer = await docxwritter.save();
    res.json({data: buffer});
  });
});

This is the 'save' fucntion of the docxwritter class (Also I am using 'docxtemplater' libary).

async save() {
    this.doc.setData(this.context);

    // Perform the templating process
    this.doc.render();

    // Get the generated DOCX content as a buffer
    const docxBuffer = await this.doc.getZip()
        .generate({type: "nodebuffer"});
    
    return docxBuffer;
  }

And this is how I am saving the file in the client side:

 const functions = getFunctions();
 const callableFunction = httpsCallable(functions, 'test');
    
 callableFunction(parameters).then((res) => {
     const wordDocumentBuffer = res.data.data;
            
     const wordDocumentBlob = new Blob([wordDocumentBuffer]);
     const wordDocumentUrl = URL.createObjectURL(wordDocumentBlob);
        
     const downloadLink = document.createElement('a');
     downloadLink.href = wordDocumentUrl;
     downloadLink.download = 'word-document.docx';
     document.body.appendChild(downloadLink);
        
     downloadLink.click();
 }).catch((err) => {
     console.log(err);
 });

I used console.log to print the buffer and the buffer.length that I am getting from the docxwritter.save() function to check if the problem is with the docx document creation. but the output I got seems to be correct:

docxBuffer length: 276528

docxBuffer:  <Buffer 50 4b 03 04 0a 00 00 00 00 00 00 00 21 00 1e 91 1a b7 4e 02 00 00 4e 02 00 00 0b 00 00 00 5f 72 65 6c 73 2f 2e 72 65 6c 73 3c 3f 78 6d 6c 20 76 65 72 ... 276478 more bytes>

also I run it with a test.js file to try save it locally using only the classes I wrote without the front-end and the file was saved correctly and looked good when I opened it.

So I am assuming that the problem is in the client side when trying to save the file in React.

Does anyone spotted what I am missing and what is the problem in my code?

Thank you.

1

There are 1 answers

2
Mario Varchmin On

Your save() method is async, so you have to call it the right way, like so:

const buffer = await docxwritter.save();

As a consequence, your arrow function needs to be async as well, (and maybe more code, that you havenā€˜t posted):

cors(req, res, async () => {
    const parameters = req.body.data;
    const analyzer = new Analyzer(parameters);
    analyzer.analyze();
    const docxwritter = new DocxWritter(analyzer);
    const buffer = await docxwritter.save();
    res.json({data: buffer});
  });