Using CSS and / or jQuery for printed pages with page breaks

I have a dynamically created html page that is designed for printing. A.

I would like to create page breaks based on div sections - where is any given div - if it does NOT fully fit the page, insert a page break in front of it.

In theory, anywhere from one div, perhaps up to 10, can fit on one printed page, so I think I will need to use jQuery to insert after the page loads.

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

  • Measure the width and height of the page (using some kind of printer object).
  • Measure each div height - and subtract from the total remaining page height
  • if (Other_space - div_height> 0) {// put it on the page} else {// insert the page first)

Is there a way to use jQuery, CSS, raw JavaScript, or something else that would lead me to this script?

+8
jquery css
source share
5 answers

Well, I spent the whole day or so figuring this out, so I wanted to post my decision on this if someone else needs an answer.

So here's what I did.

  • Generated output as usual (not for printer)
  • 2 stylesheets have been created (one for the printer and one for the screen). Measurements were taken in inches (not pixels) for all page elements that should be converted to a printed result.
  • Using jQuery, I did the following:

-> a called function that adds the original page to the 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 the height of the div, which is the page (in my case, $ ('. page'). height ();)

-> launches a function to insert div 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 style sheet has the following:

page-break-after: always;

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

After running the jQuery function above, I hid the original section containing the div elements that I wanted to move to the printed pages. Note. I could not hide this section until my jQuery measurements yielded acceptable results (in my case, I placed the entire div in the wrapper div with the id " hide_me " and set the style to height: 1px; overflow: auto; ).

I understand that it is very 50,000 feet, but I hope it is useful to you.

+3
source share

You can always insert an empty DIV tag with the CSS attribute {pageBreakBefore: 'always'} or {pageBreakAfter: 'always'} at the points in your HTML where you calculated the page borders in jQuery to check for div height or something else. But you need to have a fairly deep knowledge of the contents of the page and, possibly, indicate the font size, etc. Like pt instead of px.

See a similar query here:

Force page printing with CSS

+2
source share

Not quite what you are looking for, but look at this http://www.javascriptkit.com/dhtmltutors/pagebreak.shtml

With the optional JS trait, what you want to achieve may be possible.

0
source share

You can try using this plugin to print page elements. http://www.recoding.it/wp-content/uploads/demos/jqprint-demo.htm

This can be useful if you follow the same logic that you suggested for the desktop application. You can wrap your "pages" in a div and what do you say jqPrint to print. Page breaks can be another element or also a div, but with a class so that you know that this is a page break. For example:

 <div id="#page1" class="page"> ... </div> </div id="#break1" class="break"> </div> 

etc..

then

 $('#page1').jqprint(); 

I don't know if you are familiar with jQuery. If you do not tell us.

0
source share

The pagination point, in my opinion, is not to split things. And, as a rule, what you want not to split more often is tabular data. So this is an approach assuming you changed the format of the <div> to a table and grouped sets of rows that should not be split into <tbody> groups.

We want to tag the headers and footers to find the code, and we don’t necessarily want them to display correctly where they are described.

This calls itself when the page loads, but instead can be called immediately before printing.

 <script> $().ready(function () { $('table.paged').each(function (i, o) { BreakPages($(o)); }) }); function BreakPages(jSource) { $('body').width("7in"); var perInch = $('body').width() / 7.5; var nPageHeight = 9 * perInch; var jHeader = null; var jFooter = null; var jWrapper = jSource.clone().empty(); var jPage = null; var iPage = 0; jSource.after("<div></div>"); var jFixed = jSource.next(); function substed(jStuff) { var jCopy = jStuff.clone(); jCopy.find('span.pageNo').html(" " + iPage + " ").removeClass('pageNo'); return jCopy; } jSource.children().each( function (iChunk, oChunk) { var jChunk = $(oChunk); if (jChunk.hasClass('footer')) { jFooter = jChunk; } if (jChunk.hasClass('header')) { jHeader = jChunk; jFooter = jChunk.nextUntil('.footer').last().next(); } if (!jChunk.hasClass('sample')) { var nHeight = jChunk.height(); if (jPage) nHeight += jPage.height(); if (jFooter) nHeight += jFooter.height(); if (nHeight > nPageHeight) { if (jFooter) jPage.append(substed(jFooter)); jPage.after("<p style='page-break-after:always; height:0; width:0'>&nbsp</p>"); jPage = null; } if (!jPage) { iPage++; jPage = jWrapper.clone(); jFixed.append(jPage); if (jHeader && jHeader !== jChunk) jPage.append(substed(jHeader)); } jPage.append(jChunk); } } ); jFixed.find('span.pageCount').html(" " + iPage + " "); jFixed.find('span.pageNo').html(" " + iPage + " "); jSource.remove(); } </script> 

We decompose the table so that it is paginated.

 <body> <table> <tbody class="header"> PAGE ONE HEADER </tbody> <tbody class="header sample"> LATER PAGE HEADER (IF RELEVANT) </tbody> <tbody class="together"> ROW GROUP 1 </tbody> <tbody class="together"> ROW GROUP N </tbody> <tbody class="footer"> FOOTER </tbody> </table> </body> 

We look at the <tbody> and fill in the footer and header before any element that is destined to break the end of the page.

We mark the headers and footers with css classes and track the ability to change headers and footers by placing them in the places in the line flow where they should change, but keeping them invisible with another css class.

It is annoying that some page break implementations apply only to strictly "block" elements, so it is not defined on tbody. So I applied it to the <p> tag added to each page table.

0
source share

All Articles