8

Internet Explorer has Print Template engine, where I can use DEVICERECT element to represent a physical page, then use LAYOUTRECT element as a rectangular view to flow the HTML document through into the page and drive the pagination. That prevents lines from being cut-off in the middle between adjacent pages. This mechanism is described in details here.

Does WebKit provide a similar feature? Specifically, does PhantomJS do? I'm looking for anything that would allow to paginate an existing HTML document which doesn't have predefined page-breaks, and view it paginated as a new transformed HTML or PDF document, without lines being cut-off in middle.

noseratio
  • 59,932
  • 34
  • 208
  • 486

2 Answers2

12

The browser engine should take care of everything and you can aid it using a stylesheet for media="print".

For example to force page breaks such that every heading of level 1 or 2 (<h1> or <h2>) is placed at the beginning of a new page use page-break-before:

h1, h2 { page-break-before:always; }

In Chrome, IE & Opera you can control widows and orphans, but it hasn't landed in WebKit yet, so for now you could use

p { page-break-inside: avoid;  } 

to avoid page breaks inside paragraphs.

You can even control margins for first, left and right pages separately.

Phantom's render() uses stylesheets for print media if the output is a pdf file. rasterize.js example looks like a ready to use printing solution.

pawel
  • 35,827
  • 7
  • 56
  • 53
  • 1
    +1. Media queries and css3 page-break rules are how I handle PDF and printing when using wkpdftohtml. It tends to work more reliably in recent browsers/engines and with certain types of elements but if you control the rendering engine version and aren't relying on the client that's not such an issue. They are really useful rules so it's a shame browsers have dragged their heels on support. – SpliFF Oct 25 '13 at 02:45
2

This function working fine.

$(function () {
    $("#print-button").on("click", function () {
        var table = $("#table1"),
            tableWidth = table.outerWidth(),
            pageWidth = 600,
            pageCount = Math.ceil(tableWidth / pageWidth),
            printWrap = $("<div></div>").insertAfter(table),
            i,
            printPage;
        for (i = 0; i < pageCount; i++) {
            printPage = $("<div></div>").css({
                "overflow": "hidden",
                "width": pageWidth,
                "page-break-before": i === 0 ? "auto" : "always"
            }).appendTo(printWrap);
            table.clone().removeAttr("id").appendTo(printPage).css({
                "position": "relative",
                "left": -i * pageWidth
            });
        }
        table.hide();
        $(this).prop("disabled", true);
    });
});

This will split entire table into multiple sections...

Here is fiddle


Code taken from this article and this page.

Salman A
  • 262,204
  • 82
  • 430
  • 521
Sridhar R
  • 20,190
  • 6
  • 38
  • 35