Node-html-pdf: Div of page size render larger than page of the same defined size?

Created on 20 Oct 2016  路  13Comments  路  Source: marcbachmann/node-html-pdf

Whether I try the html-pdf command or render the page from within the API, any elements I specify with a dimension end up being bigger than they should be. Essentially if I define a div to be the same dimensions of the page it still ends up being 30% bigger than the page.

The HTML, intending to fit within a single page of US letter size:

<html>
<head>
   <title>test case</title>
</head>

<body style="background-color: yellow">
  <div style="width: 21cm; height: 27cm; border: solid 1px black;">This should be within page bounds!?</div>

</body>
</html>

The JS I was using:

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


var options = {

  // Export options
  "directory": "/tmp",       // The directory the file gets written into if not using .toFile(filename, callback). default: '/tmp'

  "width": "216mm",            // allowed units: mm, cm, in, px
  "height": "279mm",        // allowed units: mm, cm, in, px

  // File options
  "type": "pdf",             // allowed file types: png, jpeg, pdf
  "quality": "100",           // only used for types png & jpeg

  // Script options
  "phantomPath": "./node_modules/phantomjs-prebuilt/bin/phantomjs"

};

var html = fs.readFileSync('./tests/document.html', 'utf8');

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

Using node-html-pdf version 2.1.0, MacOS X 10.12, NodeJS 6.7.0

Screen shot showing issue

Most helpful comment

There is still no resolution on that issue in the phantomjs repository.
We could do a workaround and define the custom sizes by ourselves. We would have at least the correct aspect ratio which fits the wrong measurements inside the pdf.

e.g.
for A4 it is
{width: '280mm', height: '396mm'} < 210/0.75 equals 280
instead of the original
{width: '210mm', height: '297mm'}

for Letter it is
{width: '287.86mm', height: '372.53mm'} < 215.9/0.75 equals 287.8666666667
instead of the original
{width: '215.9mm', height: '279.4mm'}

You could call that using
pdf.create(html, {width: '...', height: '...'}).toFile('./out.pdf', cb)

The magic number is 0.75 here

All 13 comments

I am having the exact same issue

Yes, very same problem!

Yes, I can confirm I am encountering the same issue.

+1

I had to use html {zoom: .75;} to get the proper size.

I'm guessing this relates to the PhantomJS update? See notes here.. https://github.com/marcbachmann/node-html-pdf/pull/107

If it is the same issue, there's a long discussion at.. https://github.com/ariya/phantomjs/issues/12685

Sounds like a real mess. There was an issue introduced in Phantom v1.9 with a fix in v2.0 but apparently v2.0 also introduced a related but different issue, with similar similar symptoms, that affected different platforms. TL;DR: There's a lot of confusion.

The solution @marcbachmann mentions is popular. For me the magic number was 0.72:

html { zoom: 0.72; }

@molomby It certainly looks like the issue.

Playing around on my machine (MacBook Air 13", 10.12.1) it is about 0.65. I suspect I'll need to tune this for each host I'll be deploying to?

If you are going for A4 then check the aspect ratio on it (1:1.414). Then you can set

width: 1000px
height: 1414px

Also make sure that your elements don't have margin, because that can offset the whole page.
You only get a small white line at the bottom of the page, but since it's a white paper you don't see it.

There is still no resolution on that issue in the phantomjs repository.
We could do a workaround and define the custom sizes by ourselves. We would have at least the correct aspect ratio which fits the wrong measurements inside the pdf.

e.g.
for A4 it is
{width: '280mm', height: '396mm'} < 210/0.75 equals 280
instead of the original
{width: '210mm', height: '297mm'}

for Letter it is
{width: '287.86mm', height: '372.53mm'} < 215.9/0.75 equals 287.8666666667
instead of the original
{width: '215.9mm', height: '279.4mm'}

You could call that using
pdf.create(html, {width: '...', height: '...'}).toFile('./out.pdf', cb)

The magic number is 0.75 here

At this point I have moved on after having discovered puppeteer (developed by Google), which works well for my needs.

See: https://www.npmjs.com/package/puppeteer

I won't close this ticket, since there are likely to still be people wanting to see this ticket fixed.

This module certainly doesn't fit everybody's need. I'm also using puppeteer a bit. 馃憤
If you need headers & footers there's currently no good alternative. drawbacks everywhere 馃槩

on my side {width: '210mm', height: '297mm', borders:'1cm'} in options and zoom: 0.75; on html in CSS did the trick.

Thanks for the trick, 0.75 zoom worked for me too.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

anmolgoyal74 picture anmolgoyal74  路  4Comments

jimit-hothi picture jimit-hothi  路  4Comments

ascsi picture ascsi  路  3Comments

adman020 picture adman020  路  5Comments

tashikomaaa picture tashikomaaa  路  5Comments