node.jsmeteordownloadfile-generation

Generated docx is empty when downloaded


This is a Meteor-app. I need to generate a docx-file and download it. I am testing it by running: localhost:3000/download.

Word file is generated, but it is totally empty.

Why? I would appreciate any advice!

This is my server-side code:

const officegen = require('officegen');
const fs = require('fs');

Meteor.startup(() => {

WebApp.connectHandlers.use('/download', function(req, res, next) {

    const filename = 'test.docx';

    let docx = officegen('docx')

    // Create a new paragraph:
    let pObj = docx.createP()

    pObj.addText('Simple')
    pObj.addText(' with color', { color: '000088' })
    pObj.addText(' and back color.', { color: '00ffff', back: '000088' })

    pObj = docx.createP()

    pObj.addText(' you can do ')
    pObj.addText('more cool ', { highlight: true }) // Highlight!
    pObj.addText('stuff!', { highlight: 'darkGreen' }) // Different highlight color.

    docx.putPageBreak()

    pObj = docx.createP()

    let out = fs.createWriteStream(filename);

    res.writeHead(200, {
        'Content-Disposition': `attachment;filename=${filename}`,
        'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      });

    res.end(docx.generate(out));

    });
});

Solution

  • The problem you are facing is that docx.generate(out) is an async function: when calling res.end(docx.generate(out)) you end the request right now while you start generating the docx in the file test.docx. Hence the doc does not exist yet.

    You should modify your code to send over the file directly like this:

    res.writeHead(200, {
        'Content-Disposition': `attachment;filename=${filename}`,
        'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      });
    docx.generate(res)
    

    If you still need the file on the server side you can use another approach waiting for the file being generated (see here)