Using CSS and/or jQuery for Printed Pages with Page Breaks

OneNerd picture OneNerd · Feb 2, 2011 · Viewed 16.3k times · Source

I have a dynamically generated html page which is designed to be printed.

I would like to create page breaks based upon div sections - where any given div - if it DOES NOT fully fit on the page, insert a page break before it.

In theory, anywhere from a single div, up to perhaps 10, may fit on a single printed page, so I am thinking I will need to use jQuery to to the insertions after the page is loaded.

If this were a desktop application, I would approach it something like this:

  1. Measure the page width and height (using printer object of some sort).
  2. Measure each div height - and subtract that from page total remaining height
  3. if ( remaining_space - div_height > 0 ) { // put it on page } else { //insert page break first }

Is there any way using jQuery, CSS, raw JavaScript, or anything else, that would get me to this scenario?

Answer

OneNerd picture OneNerd · Feb 3, 2011

Ok, I spent past day or so figuring this out, so I wanted to post my solution to this in case anyone else needed the answer.

Generally speaking here is what I did.

  1. Generated output as normal (not printer-intended)
  2. Created 2 style sheets (one for printer, and one for screen). Measurements were in inches (not pixels) for all page elements to be turned into printed output.
  3. Using jQuery, I did the following:

-> called function that appends initial page to DOM - something like this

// assumes old_page_id is existing element in DOM, and var page_id = 1;
$j("<div class='page' id='" + page_id + "'><div class='print_area'></div></div>")
.insertAfter('#' + old_page_id);

-> measure height of div that is the page (in my case, $('.page').height(); )

-> ran a function to do the insertions of divs and new pages - something like this

$('div_class').each(
 function() {
  // measure height of $(this)
  // add it to running total of used space on existing page
  // if sum total exceeds remaining space, create new page, and add to that one
  // if still room left, add to this one
 }
);

Note that each page div (in my case, class='page') in the printer stylesheet has this:

page-break-after: always;

This is how I got it to create a new page on the printer where I wanted.

After running jQuery function above, I hid the original section that contained div elements I wanted to move into printed pages. Note I could not hide this section before hand because my jQuery measurements would not produce valid results (in my case, I placed all the divs inside a div wrapper with id of 'hide_me', and set the style to height:1px; overflow:auto; ).

I realize this is very 50,000 ft view, but hopefully it is helpful to you.