Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS and Image not showing in rendered pdf using html-pdf-node

I am trying to generate html to pdf in Node.js using html-pdf-node package. The page is working fine if I open the html file in the browser but when I generate it to pdf using html-pdf-node, the images and the css is not rendered in the pdf.

Here is my code:

template.html

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" type='text/css' href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <link rel="stylesheet" type='text/css' href="../css/style.css">
</head>
<body>

<div class="container">
  <div class="text-center">
    <img src="../images/logo.png" class="img-fluid" alt="Logo image">
  </div>
  

  <div class="container align-items-center atd-title text-center">
    <h3>Title Here</h3>
  </div>
  
  <div class="container align-items-center atd-container">
    <div class="row">
      <div class="col-lg-12">
        <p>Sir:</p>
        <p class="atd-paragraph">
          Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        </p>
      </div>
    </div>
  </div>
</div>

</body>
</html>

service.js

let fs = require('fs');
let path = require('path');
let ejs = require('ejs');
let html_to_pdf = require('html-pdf-node');

// Read HTML Template
let template = fs.readFileSync(path.resolve(__dirname, "../path/to/template.html"), 'utf8');
                
let html = ejs.render(template, {name: "test"});
let options = { format: 'A4' };
let file = { content: html };
let pdf = await html_to_pdf.generatePdf(file, options);
return pdf;
like image 479
Paul Digz Avatar asked Feb 24 '21 03:02

Paul Digz


People also ask

Why does HTML-PDF-node fail to load some assets?

That's because the HTML string is being passed to html-pdf-node, the other assets like images and CSS are not. html-pdf-node uses Puppeteer as a headless browser to render the web page before saving it as PDF, when it tries to resolve the assets it sends HTTP requests that just fail. The simplest option is the second one, here is a minimal example:

How can I solve the Red X error in a PDF?

Just the red X of a missing image in the PDF even though the web page itself does display the image correctly. How can I solve this? Use the absolute path to the images. You can parse the html and do a string replace first before passing it to the pdf converter. It's better to use the image resolution callback for this for this:

Is there a way to load images in HTML?

I found a simple and easy way to do it and you can put your image source path into your HTML. This will work successfully to load the images and also CSS I think so. Hopefully, this is helpful for other people.


1 Answers

That's because the HTML string is being passed to html-pdf-node, the other assets like images and CSS are not. html-pdf-node uses Puppeteer as a headless browser to render the web page before saving it as PDF, when it tries to resolve the assets it sends HTTP requests that just fail.

You have two options to solve this:

  • Create a standalone HTML file with inline CSS and images as data URLs
  • Open a web server so that the assets can be resolved without being embedded

The simplest option is the second one, here is a minimal example:

const express = require('express')
const html_to_pdf = require('html-pdf-node')
const ejs = require('ejs')
const fs = require('fs')
const path = require('path')

const app = express()
const port = 3000

const template = fs.readFileSync(path.resolve(__dirname, "./index.html"), 'utf8')
const content = ejs.render(template, { title: "Awesome title!" })
fs.writeFile(path.resolve(__dirname, "./public/index.html"), content, () => {
    app.use(express.static('src/public'))

    const server = app.listen(port, async () => {
        const url = `http://localhost:${port}`
        const options = { format: 'A4', path: 'output.pdf' }
        const file = { url }
        await html_to_pdf.generatePdf(file, options)

        server.close()
    })
})

I've created a working project here: https://github.com/Guerric-P/html-pdf-node-demo

like image 151
Guerric P Avatar answered Oct 17 '22 03:10

Guerric P