How can I count CSS page breaks for printed HTML?

21,120

Solution 1

Ive been able to implement page breaks whilst creating PDFs for print, using wkhtmltopdf. though im not sure if my solution is compatible with non webkit browsers but im sure you can get a vendor prefix for all the broswers if needs be.

Heres what i did, using page-break-inside: avoid; & page-break-after: always;

Then using jquery I worked out the heights of my sections and calculated (if the page size is going to be a4) how many times a break occured, and numbered the pages dynamically using jquery and pdf footers (before creating the pdf) so when the user downloaded the pdf it was numbered correctly.

What I reccomend is setting the page up (as the print stylesheet) so that page numbers are visible at these heights in the page, using absolute positionsing perhaps.

but I dont think this is failsafe.

Give them a PDF to print, then you have more control and dont have to worry about the web-print stylesheet, provided the PDF download link is prominently dispalyed.

Solution 2

I'm assuming you place a CSS page break at the end of each report and not manually at the end of each page. So your problem is to know when a page break will occur naturally within a long HTML document. The answer is - you can't. Even if you know how many lines of a table fit on a page (for example) you'll only know that for a given page size and print settings. If somebody decides to print your report on legal paper scaled 200% then your document will never know that. In my opinion, your options are 1) guess or 2) don't worry about it.

Share:
21,120
Carvell Fenton
Author by

Carvell Fenton

Software and tech guy... always learning. Currently working with C++, Qt, a little Python, and database stuff. Involvement with high throughput computing. Previous experience with jQuery, php, and MySQL. Keen interest in user interface design and human-computer interaction. Also a Western horse rider, PC gamer, lover of space sims, RPGs, etc.

Updated on January 15, 2020

Comments

  • Carvell Fenton
    Carvell Fenton over 4 years

    I am generating reports using HTML and I am using CSS to control the page breaking using page-break-after, etc. I have given the user the option to print multiple reports at once, which I create as sections of a single dynamically generated HTML document. Making it a single document allows it to be a single print job to avoid print spooling issues.

    My problem is this: I would like to number the pages of a section of the larger dynamic HTML in the format "page x of n". However, if I let the printer do it, it sees the document (rightly) as a single document and numbers the whole document.

    Is there any way I could determine when the CSS page breaks are going to occur, so I could count them for a section before printing, and put my own numbering (HTML element for example) in for the sections in the long single document?

    It seems like there should be a way for me to do this, but over the past few days the solution eludes me, so I thought I would ping Stackoverflow.

    UPDATE: What I ended up doing:

    I have accepted Christopher's answer because although I didn't use it exactly, it pointed me in the right direction.

    I ended up doing calculations on the content using jQuery, based on the paper size being printed to, margins, font size, etc. and then adding elements for page breaks that have CSS for page breaking. I track how many of the page break divs are added, and then update the html "page x of n" information in each page break div once all the content is processed. That allowed me to avoid having to know how many pages there would be at the beginning (thanks jQuery .each).

    Obviously there are some issues with this solution:

    1. The "page x of n" elements don't appear as true footers, but rather at the bottom of the content on each page. In my situation that is an acceptable compromise.

    2. Splitting content elements that were in themselves larger than a page, especially considering most of the content is generated by php, got a little complicated. I made it work, but again, it requires assumptions that could break with printing variations.

    3. The calculations depend on assumptions about the printed paper size, margins, font size, etc. In my situation running on an intranet, that is again an acceptable compromise because I can control those options. Additional code can be added to handle some amount of variation in future (paper size for example).

    This solution, although not perfect and a little "brittle", solves my problem, allows me to print multiple reports at once avoiding printer spooling timeouts, keeps track of and restarts page numbering, and avoids generating PDFs as an intermediate step for printing.

    I found this a oddly hard nut to crack, so I would still appreciate opinions and input on the solution.

    Thanks!

    UPDATE 2: Final solution... avoid the headaches yourself:

    Although I went perhaps farther than I should have with this approach, with some small successes, in the end the solution really wasn't one because it just ended up being far too "brittle" to changes. Any change in report format, new content added to existing reports, paper size etc. broke the calculations and just ended up in a ridiculous amount of extra work!

    So, the end solution? "Resistance is futile!" Just do the reports as PDFs. You may commence the "we told you so" chorus if you wish, I can take it ;-)

    I went with the TCPDF library, which has been excellent, if a little tough going to get started. The examples are very helpful. Now I have complete customization over the report, and everything get generated as it should. Mulitple reports are easily created as a single PDF (preventing the print spooling issue) with page groups that allows for the numbering to work exactly as I need.

    So, if you are trying to do something like this, I would recommend you cut to the chase, skip the frustration with HTML/CSS type reports, and do PDFs.

  • Carvell Fenton
    Carvell Fenton over 13 years
    You are right about the printing variation. I am putting the CSS page break at the end of each report. This is on an intranet, so although the people could change the printing setup, they generally will not, and if they do, I can tolerate the solution "breaking" in those cases because my response can be "don't do that!" ;) But I am getting concerned that you may be right and this may not be possible...
  • Sparafusile
    Sparafusile over 13 years
    If you all used the same hardware and same setup I would simply put each report in a separate DIV and then use theDiv.clientHeight to find out how long it is. If you know what size DIV will fit on a printed page you should know how many pages there are. You could then absolutely position en element with the page number where it belongs. It would take some work, but I think it would work with enough trial and error.
  • Christopher
    Christopher over 13 years
    given the other answers, i would agree that its not failsafe, but i would reccomend supplyign the user witha pdf (whcih you can control) and then you wont ahve to worry about how they print your page.
  • Carvell Fenton
    Carvell Fenton over 13 years
    I will look into the clientHeight option.
  • ANeves
    ANeves over 13 years
    But then the element would change the div's size too... that should be fun to watch.
  • Carvell Fenton
    Carvell Fenton over 13 years
    I did check into wkhtmltopdf. I was trying to avoid pdf for some other reasons related to the system, but if concensus said it was the only way to solve the problem, I could reconsider.
  • Sparafusile
    Sparafusile over 13 years
    @ANeves not when it's absolutely positioned.
  • Christopher
    Christopher over 13 years
    I shied away from producing PDF's when i first found a need, thinking it would be too much effort, but ive found wkhtmltopdf a pleasure to work with, with all the dependibility of webkit... its not as hard or frustrating as it may seem at first. I highly recommend it.
  • Carvell Fenton
    Carvell Fenton over 13 years
    I will have to do some more googling concerning wkhtmltopdf to see if I can find some sites to get me started so I can decide if this is a good option for me. I was trying to avoid all the page size calculating, but both of the answers here have me doing that one way or another.
  • Christopher
    Christopher over 13 years
    with wkhtmltopdf,t he page numbering can be dont pretty easily without any calulations beyond what number to display (ie not determineing height shenanagens). if you post a question asking how to easily set it up with some nifty examples,(just comment a link to it here) i wouldnt hesitate to give a (to the best of my knowledge) thorough answer :)
  • Carvell Fenton
    Carvell Fenton over 13 years
    I think I will take you up on that because the information on the web seems a little sparse for a beginner. So your suggestion is to ask a specific question about page numbering in wkhtmltopdf, and link back to this question?
  • Carvell Fenton
    Carvell Fenton over 13 years
    @Christopher Voted to delete my other question. It was simply too convoluted and looked like I just wanted someone to solve this problem for me. Not my intent. I would be interested in any examples you were willing to provide.