How to get correct rendering size when printing ht

2020-06-03 04:37发布

问题:

I have trouble understanding how to render html elements with correct size when printing them to A4 size paper.

To illustrate my purpose, I simplified my code to a html page with a single red bordered table that should be 210mmx297mm (A4 paper size):

<!DOCTYPE html>
<html>
  <head>
    <style>
      @page
      {
        size: 210mm 297mm portrait; /* Set paper size to A4 (portrait) */
      }
		
      html, body 
      {
        width: 210mm;
        padding:0;
							 
        margin: 0 auto; /* Left, right are auto for body to appear as centered on screen */				                
      }
      html
      {
         background: rgb(204,204,204); /* gray client window for screen (so as to emphase the body as looking as A4 paper) */
      }			

      table
      {
        width:100%;
        height:297mm;
        -moz-box-sizing: border-box;
			
        border: solid 3px red;
        border-spacing:0;
        border-collapse: collapse;
      }
      td
      {
        padding: 0;
        text-align: center;
        box-shadow: inset 0 0 0 1000px white;
      }
    </style>
  </head>
  <body>
    <table><tr><td>Hello world!</td></tr></table>    
  </body>
</html>

  • When I try to print this with Firefox (49.0.2), and carefully setting all margins to 0 and rendering size to 100%, I get a table which obviously is oversized:

  • If I select 'Adapt to page' for rendering size, I get a table which obviously is downsized:

  • I'm not much more lucky if I try with Chrome (54.0.2840.87 m)

I tried to force size to 210mmx297mm all the way round in the css, but there's still something wrong. I can't figure out what it is ... either a bug in rendering engine or setting missing in my code.

Note

Contextually I'm trying to create automatic reports all in html+css+javascript so they can be easily be viewed and eventually printed to pdf or paper from a web-browser. Cover page should be filled with some image up the very edges of A4 paper.

Here is some more complete example:

Example (JSFiddle)

I'm almost there, everything display nicely on screen (firefox+chrome) but there's still those margins when printing (printing works with firefox+nomargin+adaptsize only ... chrome is bugged for repeating table header/footer when printing).

回答1:

You are tackling a difficult problem which is a bane of many programmers' existence. Printing from HTML and ensuring compatibility with different browsers is basically a unicorn. You shouldn't manage that concern yourself. The quirks of CSS styling and the fragmentation of the browser ecosystem will make sure you don't succeed.

My advice is that you take a look at a PDF generator API like PDF Kit or iText.

From my research, page and form printing is especially problematic on Firefox. As you've noticed from first hand experience, you can't manage margins in a sane way. I also tried with Firefox 49.0.2 without success.

I thought about using @media print{} but Firefox was unwilling to collaborate.

That being said, your code worked just fine for me running Chrome on the version you mentioned. Note that I set the margins to 'none'.



回答2:

Cover page should be filled with some image up the very edges of A4 paper.

You're never going to satisfy this requirement. Trust me, I've been doing dashboards and reports on the web for a long time and you simply don't get fine-grained control over rendering like this. The web isn't designed for it.

You can still generate some great reports if you're willing to work within a margin and not try for pixel-perfect layouts. Web reports can look super sharp and you can cover multiple media with one code base.

But for situations where pixel-perfect rendering matters, in addition to control over page breaks and such, only a PDF library will suffice. There are some good ones out there--I've had success with PDFSharp.

Why don't you display a cover image that doesn't span the entire page?



回答3:

You could use phantomjs to render your pdf (you ask for pdf eventually). In php I have successfully used https://github.com/kriansa/h2p to generate pdf's. (also with rendering javascript based charts with d3.js). It is not easy but with headless browsing you can make it work.