Plugging together the Node document pipeline

This is the third part of the Document Generator series, where we‘re plugging together the two distinct parts of our pipeline.

In the first part we took a look at automatically generating Word documents with pre-made templates. The second part investigated building PDF files from any Word document that can be automated.

Motivation

So, you might ask, why we‘re taking such a diversion from just plain out generating PDFs within our backend. I want to give some examples from my experience:

  • PDF generation libraries are flexible but with their flexibility comes a lot of complexity that needs to be maintained, which can be very expensive
  • while debugging might be easier, the visual appearance often comes second with PDF libraries
  • no non-technical people can work on the templates, so the work on them has to be done by highly-skilled expensive workers

Thus the velocity of your team can be highly increased by using Word templates instead of manually building PDFs.

Plugging together

If we take a look at our result from the first post, we can see that the generate returns a Readable. But we could instead wrap the part until we turn the Buffer into a Readable and call this function instead. As our convertWordToPdf function also takes a Buffer, we can then pipe the Word result.

Let‘s revisit the API endpoint and change it a bit to return a PDF instead:

async function pdfFromTemplate(document: string, payload: any) {
    const word = await generate(document, payload);
    const pdf = await convertWordToPdf(word.buffer);

    const readable = Readable.from(pdf);

    return { pdf: readable, filename: word.filename };
}

router.get('/generate/:documentId', async (req, res) => {
    try {
      const generated = await pdfFromTemplate(req.params.documentId, req.query);
  
      res.setHeader(
        'Content-Disposition',
        'attachment; filename="' + encodeURI(generated.filename) + '"'
      );
      res.setHeader(
        'Content-Type',
        'application/pdf'
      );
  
      return generated.pdf.pipe(res);
    } catch (error) {
      console.error(error);
      if (error.name === 'ValidationError') {
        res
          .status(400)
          .send({ message: 'validation failed', error: error.message });
      } else {
        res.status(500).send({ message: 'Could not generate documents.' });
      }
    }
});

Now, your backend returns sweet PDF files. You could of course also run both endpoints in parallel and offer your users the choice.

Word Document Pipeline - Tim Weiß
Making PDFs from Word files in Node with LibreOffice’s headless converter
Consider this part 2 of the Generating Word Documents series. While your customers might manually convert their downloaded Word reports to PDF, there’s a lot of power in automatically converting them to PDF. For example, you probably don’t want to send invoices as Word documents, but maybe you
Generating Word documents on the fly with docxtemplater in Node.js
Introduction If you’re working on productivity software, chance is high that somebody will eventually ask you for some reports. Now, often PDF does the job just right, but there are many options to choose from and most packages either give you a lot of power or too little. They