mayank bisht
mayank bisht

Reputation: 618

How to convert html to pdf in node.js using `html-pdf`module



I am generating invoice using html-pdf module.
I am able to generate pdf when I am passing web page local address, i.e stored in folder.
But my requirement is to hit API, and then generate pdf file.

Can I do that using html-pdf module, or there is some other module that can do that?



Code

var fs = require('fs');
var pdf = require('html-pdf');
var html = fs.readFileSync('./test/businesscard.html', 'utf8');
var options = { format: 'Letter' };

pdf.create(html, options).toFile('./businesscard.pdf', function(err, res) {
  if (err) return console.log(err);
  console.log(res); // { filename: '/app/businesscard.pdf' }
});


Please help.

Upvotes: 4

Views: 12417

Answers (2)

Abolfazl Roshanzamir
Abolfazl Roshanzamir

Reputation: 14792

You can send the created pdf file to the client without saving the file in the root directory of your project:

const fs = require('fs')
const pdf = require('html-pdf');

app.get('invoice/generatePDF', (req, res, next) => {

    const html = fs.readFileSync('./template.html').toString() // './test/businesscard.html'
    var options = { format: 'Letter' };

    pdf.create(html, options).toStream(function (err, stream) {
        if (err) {
            console.log(err);
            res.status(500).send("Some kind of error...");
            return;
        }
        stream.pipe(res)
    })

})

If you want to use html-pdf in nestjs, first of all import Res from @nestjs/common and Response from express then

import { Controller, Get, InternalServerErrorException, Req, Res, } from '@nestjs/common';
import * as pdf from 'html-pdf'
import { readFileSync } from 'fs'
import { Response, Request } from 'express';


@Controller()
export class AppController {

  @Get()
  async convertHtmlToPDF(@Res() response: Response) {
    const html = readFileSync('./public/index.html').toString()
    var options = { format: 'Letter' };

    pdf.create(html, options).toStream(function (err, stream) {
      if (err) {
        throw new InternalServerErrorException({ status: 500, messsage: "Some kind of error..." })
      }
      stream.pipe(response)
    })
  }
}

Upvotes: 1

HomerPlata
HomerPlata

Reputation: 1787

If I'm reading this correctly, you want to generate a pdf from the html file, and then return it to the browser/client?

This should do it:

var fs = require('fs');
var bodyParser = require('body-parser');
var pdf = require('html-pdf');

app.post('/product/invoice', function (req, res) {
    var htmlPath = req.body.htmlPath;
    if (!htmlPath){
        res.status(400).send("Missing 'htmlPath'");
        return;
    }
    var html = fs.readFileSync(htmlPath, 'utf8');
    // you may want to change this path dynamically if you also wish to keep the generated PDFs
    var pdfFilePath = './businesscard.pdf';
    var options = { format: 'Letter' };

    pdf.create(html, options).toFile(pdfFilePath, function(err, res2) {
        if (err){
            console.log(err);
            res.status(500).send("Some kind of error...");
            return;
        }
        fs.readFile(pdfFilePath , function (err,data){
            res.contentType("application/pdf");
            res.send(data);
        });
    });
});

You need to POST to this endpoint with htmlPath as a parameter (which will be, from your initial example, ./test/businesscard.html) - make sure this is properly URL encoded.

Upvotes: 4

Related Questions