HTML-PDF Example

This is an implementation of the library using Meteor and React, which also shows an example of how to download the pdf generated.

PACKAGE JSON Configuration

The following is an example of how the library should look like in the package.json with a stable version:

{
  "dependencies": {
    "html-pdf": "2.2.0"
  }
}

Server side

The following function uses the create method of the library, with a given html string and an object with valid options (see client side example or options in the library's documentation). The toFile method stores it in the given path.

export const createHtmlPdf = function(html, options, fileName) {
  return new Promise((resolve, reject) => {
    htmlPdf.create(html, options).toFile('server/path/to/file/' + fileName + '.pdf', function (error, response) {
      if (error) {
        reject(error);
      } else {
        resolve(response.filename);
      }
    });
  });
};

The meteor call in Meteor:

'createPDF'(html, options, fileName) {
  try {
    Promise.await(createHtmlPdf(html, options, fileName));
    return;
  } catch (exception) {
    throw new Meteor.Error();
  }
};

Client side

The following function does the Meteor call, and if no errors were returned, it redirects to the url where the pdf will be downloaded.

const convertToPDF = (pdfHtmlString, fileName, callback) => {
  const css = "<link href='path/to/css' rel='stylesheet'>";
  const fonts = "<link href='path/to/fonts' rel='stylesheet'>";
  // This step is not necessary if the pdfHtmlString parameter contains the whole html, and not just the body
  const html = "<!DOCTYPE html><html><head>" + css + fonts +
    "</head><body>" + pdfHtmlString + "</body></html>";
  // Example of valid options
  const options = {
    format: 'A4',
    orientation: "portrait",
    header: {"height": "10mm"},
    footer: {"height": "10mm"}
  };
  Meteor.call('createPDF', html, options, fileName, function(error) {
    if (error) {
      callback('Error in PDF convertion');
    } else {
      window.open("/published/path/to/file/" + fileName);
      callback();
    }
  });
};

This function uses the React DOM Server to transform a react component into an html string, and then calls the convert to PDF function.

convertToPDF() {
  // The button to generate pdf is disabled to avoid mutiple generations of the pdf
  this.setState({pdfButtonDisabled: true});
  const pdfHtmlString = ReactDOMServer.renderToString(<PDFreactComponent />);
  const self = this;
  convertToPDF(pdfHtmlString, 'fileName', (error) => {
    if (error) {
      console.log('Error while converting to PDF');
    }
    // PDF generation button is enabled again
    self.setState({pdfButtonDisabled: false});
  });
}

For pdf upload (server side publication)

To publish the pdf file generated, the body-parser library and the node js filesystem were used.

import bodyParser from 'body-parser';

Picker.middleware( bodyParser.json() );
Picker.middleware( bodyParser.urlencoded( { extended: false } ) );

const GET = Picker.filter(function(request, response) {
  return request.method === "GET";
});

GET.route('/published/path/to/file/:filename', function(params, req, res) {
  const fs = require('fs');
  const filePath = 'server/path/to/file/' + params.filename + '.pdf';
  fs.readFile(filePath, (error, data) => {
    if(error) {
      res.end("");
      console.log(error.message);
    }   
    res.writeHead(200, {
      'Content-Type': 'application/pdf',
      'Content-Disposition': 'attachment; filename=' + params.filename + '.pdf',
      'Content-Length': data.length
    });
    res.end(data);
  });
});