eKoopmans / html2pdf.js

Client-side HTML-to-PDF rendering using pure JS.
MIT License
4.09k stars 1.38k forks source link

width of html is compressed #142

Closed webrexRavi closed 5 years ago

webrexRavi commented 6 years ago

Element which i render is looks great in html but when i convert it using html2pdf() it's compresses the size of it, i am get what the issue is, when i am setting height width it is changing only changes size of document only i want to change width of image to full width of document.

My HTML Normal Html

Exporting Image #Data Print data

subatomicglue commented 5 years ago

I am also getting this same issue where the width of resulting PDF is 70% what it should be.
And, manually using html2canvas + jsPDF directly works perfectly! (but no links)

configuration:

      let doc_width = 8.27;  // A4 measures 210 × 297 millimeters or 8.27 × 11.69 inches
      let doc_height = 11.69;
      let aspect = doc_height / doc_width;
      let dpi = 120; // targeting ~1200 window width
      let img_width = doc_width * dpi;
      let img_height = doc_height * dpi;
      let win_width = img_width;
      let win_height = img_height;

      // https://html2canvas.hertzen.com/configuration
      let html2canvasOpts = {
        scale: img_width/win_width,   // equals 1
        width: img_width,
        height: img_height,
        windowWidth: win_width,
        windowHeight: win_height,
      };

      // https://rawgit.com/MrRio/jsPDF/master/docs/jsPDF.html
      let jsPDFOpts = {
        orientation: 'portrait',
        unit: 'in',
        format: [doc_width, doc_height]
      };

then using html2pdf.js (npm install --save html2pdf.js 0.9.1 in an Angular 5 app) Results in 70% width from what I would expect:

      // https://github.com/eKoopmans/html2pdf
      html2pdf().set({
        margin:       [0.01, 0.01, 0.01, 0.01],
        filename:     'html2pdf.pdf',
        image:        { type: 'jpeg', quality: 0.98 },
        html2canvas:  html2canvasOpts,
        jsPDF:        jsPDFOpts,
      }).from( document.getElementById('dom-to-print') ).save();

If I call the html2canvas (1.0.0-alpha.12) and jsPDF (1.4.1) manually, then I get a perfect PDF page:

let canvas = await html2canvas( document.getElementById('dom-to-print'), html2canvasOpts );
var img = canvas.toDataURL("image/jpeg");
var pdf = new jsPDF(jsPDFOpts);
pdf.addImage(img, 'JPG', 0, 0, doc_width+.16, doc_height); // no idea why the extra .16 is needed...
pdf.save('jsPDF.pdf');

Resulting PDFs:

Using html2pdf (width is narrow): html2pdf.pdf

Using jsPDF (looks good!): jsPDF.pdf

subatomicglue commented 5 years ago

My html content is like so:

HTML template in Angular5

<div id='dom-to-print'>
  <div id='header'>
    <div id='left' style='line-height: 40px;'>Company Summary</div>
    <div id='right'><img src='assets/logo.png'></div>
  </div>
  <div id='body'>
    <H1><img width='30px' src='assets/logo2.png'> Fake Company</H1>
    The quick fox jumped over the brown lazy dog.
    Jack quietly moved up front and seized the big ball of wax.
    Few black taxis drive up major roads on quiet hazy nights.
    Just poets wax boldly as kings and queens march over fuzz.
    Bored? Craving a pub quiz fix? Why, just come to the Royal Oak!
    Quincy Pondexter blocked five jams against the Wizards!
    Crazy Frederick bought many very exquisite opal jewels.
    A quivering Texas zombie fought republic linked jewelry.
    Grumpy wizards make toxic brew for the evil queen and jack.
    The job of waxing linoleum frequently peeves chintzy kids.
    Back in June we delivered oxygen equipment of the same size.
    Just keep examining every low bid quoted for zinc etchings.
    How razorback-jumping frogs can level six piqued gymnasts!
    A quick movement of the enemy will jeopardize six gunboats.
    All questions asked by five watched experts amaze the judge.
    Bobby Klun awarded Jayme sixth place for her very high quiz.
    The wizard quickly jinxed the gnomes before they vaporized.
    Zelda might fix the job growth plans very quickly on Monday.
    Zack Gappow saved the job requirement list for the six boys.
    Jackie will budget for the most expensive zoology equipment.
  </div>
  <div id='body' style='display: flex;'>
    <div id='left'>
      <H1><img width='30px' src='assets/logo2.png'> Things They Do</H1>
      The quick fox jumped over the brown lazy dog.
      Jack quietly moved up front and seized the big ball of wax.
      Few black taxis drive up major roads on quiet hazy nights.
      Just poets wax boldly as kings and queens march over fuzz.
      Bored? Craving a pub quiz fix? Why, just come to the Royal Oak!
      Quincy Pondexter blocked five jams against the Wizards!
      Crazy Frederick bought many very exquisite opal jewels.
      A quivering Texas zombie fought republic linked jewelry.
      Grumpy wizards make toxic brew for the evil queen and jack.
      The job of waxing linoleum frequently peeves chintzy kids.
      Back in June we delivered oxygen equipment of the same size.
      Just keep examining every low bid quoted for zinc etchings.
      How razorback-jumping frogs can level six piqued gymnasts!
      A quick movement of the enemy will jeopardize six gunboats.
      All questions asked by five watched experts amaze the judge.
      Bobby Klun awarded Jayme sixth place for her very high quiz.
      The wizard quickly jinxed the gnomes before they vaporized.
      Zelda might fix the job growth plans very quickly on Monday.
      Zack Gappow saved the job requirement list for the six boys.
      Jackie will budget for the most expensive zoology equipment.
    </div>
    <div id='right'>
      <H1><img width='30px' src='assets/logo2.png'> Things They Don't</H1>
      The quick fox jumped over the brown lazy dog.
      Jack quietly moved up front and seized the big ball of wax.
      Few black taxis drive up major roads on quiet hazy nights.
      Just poets wax boldly as kings and queens march over fuzz.
      Bored? Craving a pub quiz fix? Why, just come to the Royal Oak!
      Quincy Pondexter blocked five jams against the Wizards!
      Crazy Frederick bought many very exquisite opal jewels.
      A quivering Texas zombie fought republic linked jewelry.
      Grumpy wizards make toxic brew for the evil queen and jack.
      The job of waxing linoleum frequently peeves chintzy kids.
      Back in June we delivered oxygen equipment of the same size.
      Just keep examining every low bid quoted for zinc etchings.
      How razorback-jumping frogs can level six piqued gymnasts!
      A quick movement of the enemy will jeopardize six gunboats.
      All questions asked by five watched experts amaze the judge.
      Bobby Klun awarded Jayme sixth place for her very high quiz.
      The wizard quickly jinxed the gnomes before they vaporized.
      Zelda might fix the job growth plans very quickly on Monday.
      Zack Gappow saved the job requirement list for the six boys.
      Jackie will budget for the most expensive zoology equipment.
    </div>
  </div>
  <div id='footer'>
    <div id='left'>
      <div><strong>View this in the app</strong></div>
      <div><a href="http://www.go.to/some/place">http://www.go.to/some/place</a></div>
    </div>
    <div id='right'>
      <div><strong>Last Updated</strong></div>
      <div>03/13/2020</div>
    </div>
  </div>
</div>

CSS

  button {background-color:#ff0000;color:#ffffff;}
  #dom-to-print {
    position: relative;
    width: 100%;
    height: 100vh;
    background-color: #ffffff;
    color: #000000;
    font-family: Helvetica, Arial, Sans-Serif;
  }
  #header {
    background-color: #5577aa;
    color: #ffffff;
    font-size: 2rem;
    font-weight: 700;
    height: 4.7rem;
    margin: auto;
    display: flex;
  }
  #left {
    padding: 1rem;
    flex: 0 0 50%;
    vertical-align: middle;
  }
  #right {
    flex: 1;
    padding: 1rem;
    text-align: right;
    vertical-align: middle;
  }
  #header #right img {
    width: 100px;
  }
  #body {
    font-size: 1rem;
    font-weight: normal;
    padding: 3rem;
    line-height: 1.5rem;
  }
  h1 {
    border-bottom: 1px solid #333333;
    padding-bottom: 0.7rem;
  }
  a, a:hover, a:active {
    font-weight: normal;
    color: #333333;
  }
  #footer {
    position: absolute;
    bottom: 0;
    width: 100%;
    display: flex;
    height: 64px;
    background-color: #dddddd;
    color: #000000;
    font-size: 0.8rem;
  }

logo logo2

subatomicglue commented 5 years ago

If I comment out width, then the width is correct, but the height overflows:

let html2canvasOpts = {
        scale: 1,       //  img_width/win_width // is 1,
        //width: img_width,
        height: img_height,
        windowWidth: win_width,
        windowHeight: win_height,
      };

html2pdf (15).pdf

subatomicglue commented 5 years ago

Multiplying the windowWidth does nothing:

      let html2canvasOpts = {
        scale: 1,
        width: img_width,
        height: img_height,
        windowWidth: win_width * 0.7,   // 1.3 also does nothing, neither does 2, 8, etc...
        windowHeight: win_height,
      };
subatomicglue commented 5 years ago

Width and Height in my case are needed to increase the DPI. The DPI is just too pixelated using default settings.

let html2canvasOpts = {
        scale: 1,
        windowHeight: win_height * 0.796, // ~1118px?
      };

Too pixelated: html2pdf (41).pdf

subatomicglue commented 5 years ago

Using scale, I can affect the DPI

let html2canvasOpts = {
        scale: 2.5,
      };

But the virtual browser height is off, the footer is now too high: html2pdf (51).pdf

And then, using width/height and windowWidth/windowHeight creates chaos... but.... If I set

      let html2canvasOpts = {
        scale: 2.5,
        windowHeight: doc_height * 96 - 3   //  offset by -3 to avoid the 2nd page because of margins
      };

Then it works!
So it looks like DPI should not be manipulated with width/height and windowWidth/windowHeight... but instead with scale... (strange it works manually using html2canvas + jsPDF though!) html2pdf (62).pdf

Some Caveats:

The link in the footer is now NOT clickable... 👎 (but a link up in the body text IS clickable!) 👍

Move your mouse cursor up a bit, you'll see that the footer's link IS THERE, but it's floating up where the default windowHeight was before I set it to doc_height * 96 - 3. 👎

The incorrectly generated "link" floats even higher when generated using Edge browser. 👎

Of course, to have a footer, I am using height: 100vh, which is affected by the virtual window height

Incorrect Hyperlink click areas seems like a different problem, Moving to a new topic: https://github.com/eKoopmans/html2pdf/issues/174

subatomicglue commented 5 years ago

@webrexRavi what did your code look like to render your PDF? Were you specifying width/height on the html2canvas options? If so, take a look at my tests and see if that helps you.

Dante-dan commented 5 years ago

+1

Dante-dan commented 5 years ago

if I set

const opt = {
        // margin: 5,
        filename: 'myFile.pdf',
        html2canvas: {
          // scale: 2.5,
          useCORS: true,
          // width: element.offsetWidth,
          // windowWidth: element.offsetWidth * 2,
        },
        jsPDF: { unit: 'pt' },
      };

the width of html is compressed ,and scale is useless

I set the width, the page width is right. But the content width is compressed

talamihg commented 5 years ago

What ended up being the fix for this issue?

I just downloaded the latest bundled minified version of html2pdf and this is happening to me.

webrexRavi commented 5 years ago

What ended up being the fix for this issue?

I just downloaded the latest bundled minified version of html2pdf and this is happening to me.

use html2canvas with custom JS

WebDevVijay commented 5 years ago

@subatomicglue I have implemented the same in angular 8.1 https://github.com/eKoopmans/html2pdf.js/issues/142#issuecomment-437093743 but generated PDF stretched.

See attached PDF html2pdf.pdf file

sugionosihuahua commented 2 months ago

no fix yet?