marcbachmann / node-html-pdf

This repo isn't maintained anymore as phantomjs got dreprecated a long time ago. Please migrate to headless chrome/puppeteer.
MIT License
3.55k stars 544 forks source link

Generated PDF has no style, no images. #666

Open Scrashdown opened 2 years ago

Scrashdown commented 2 years ago

Hello,

The header of my HTML file looks like this:

<head>
        <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="style.css">
</head>

Somewhere else in my HTML file, I have an image:

<img src="img/profile.jpg">

I am trying to compile with the following script (main.js):

let src = fs.readFileSync(`./src/in.html`, 'utf-8')
const options = {
        "base": `file://${__dirname}/src/`,
        "format": "A4",
        "orientation": "portrait"
}
pdfc.create(src, options).toFile(`./out/out.pdf`, (err, res) => {
        if (err) return console.log(err)
        console.log(res)
})

Here is the file structure:

|- main.js
|- src/
   |- in.html
   |- style.css
   |- img/
      |- profile.jpg
|- out/

The resulting PDF has no style, no images... I'm guessing something is wrong with options.base, but it is pointing to the right directory and the files are where the HTML file expects them to be. Am I passing the options wrong?

Thanks.

jsantoyov commented 2 years ago

I had the same problem, I solved just adding the localUrlAccess option, this is my code:

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

    var html = fs.readFileSync('./templates/index.html', 'utf8');
    let base = path.resolve('./templates/static') + '/';
    base = base.replace(new RegExp(/\\/g), '/');

    var options = {
        "format": "Letter",
        "base": "file:///" + base,
        "localUrlAccess": true, // set this to true to enable local file access
    };

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

I hope you find it helpful 👍

Gotvna commented 2 years ago

Use base64 image

Rohanpatel512 commented 2 years ago

I tried using localUrlAccess: true for my code, but it still didn't work for me.

Gotvna commented 2 years ago

Leave this package if you want to nice ans easy css

liam-jones-lucout commented 2 years ago

I tried using localUrlAccess: true for my code, but it still didn't work for me.

You also need to supple the base value. That is an absolute path to your html base directory. so if your files are stored at

/home/hello/world

your base needs to be

file:///home/hello/world

this is what worked for me:

import pdf from 'html-pdf';
import {readFile} from 'fs/promises';
import {fileURLToPath} from 'url';
import path from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

async function main() {
  const file = await readFile("./README.html");
  await new Promise(res => pdf.create(file , {
    localUrlAccess: true,
    format: 'A4',
    base: "file:///" + __dirname + "/",
  }).toFile('./README.pdf', function() {res()}));
}

main();