Photo by Hello I’m Nik on Unsplash
A HTML report that is going to be printable, and it has “sections” that should start in a new page.
Is there any way to put something in the HTML/CSS that will signal to the browser that it needs to force a page break (start a new page) at that point? Especially for creating a PDF with HTML and transfored by PDFKit.
Answers:
- For print (Chris Doggett)
Can I force a page break in HTML printing? — Stack Overflow
Add a CSS class called “pagebreak” (or “pb”), like so:
1
2
3
| @media print {
.pagebreak { page-break-before: always; } /* page-break-after works, as well */
}
|
Then add an empty DIV tag (or any block element that generates a box) where you want the page break.
1
| <div class="pagebreak"> </div>
|
It won’t show up on the page, but will break up the page when printing.
P.S. Perhaps this only applies when using -after
(and also what else you might be doing with other <div>
s on the page), but I found that I had to augment the CSS class as follows:
1
2
3
4
5
6
| @media print {
.pagebreak {
clear: both;
page-break-after: always;
}
}
|
- For PDFKit (Andrew)
Add a page break in html for PDFKit in Swift — Stack Overflow
By changing it to page-break-before
instead of page-break-after
it seems to work. This is what I changed your contextString to, I used a multiline string as it is easier to read and gave it some clearer content.
1
2
3
4
5
| let contextString = """
<p>Content in page 1</p>
<p style=\"page-break-before: always;\"></p>
<p>Content in page 2</p>
"""
|
Here is a very simple example that you could drop into Xcode.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| class ViewController: UIViewController { let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false button.setTitle("Print", for: .normal)
button.setTitleColor(.systemBlue, for: .normal)
button.addTarget(self, action: #selector(tapped), for: .touchUpInside) NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
])
view.backgroundColor = .systemBackground
} @objc func tapped() { let contextString = """
<p>Content in page 1</p>
<p style=\"page-break-before: always;\"></p>
<p>Content in page 2</p>
""" let print = UIMarkupTextPrintFormatter(markupText: contextString) let render = UIPrintPageRenderer()
render.addPrintFormatter(print, startingAtPageAt: 0) let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
render.setValue(page, forKey: "paperRect")
render.setValue(page, forKey: "printableRect") let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, .zero, nil) for i in 0..<render.numberOfPages {
UIGraphicsBeginPDFPage();
render.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
}
UIGraphicsEndPDFContext(); let av = UIActivityViewController(activityItems: [pdfData], applicationActivities: nil) self.present(av, animated: true, completion: nil)
}
}
|
Here is a gif of it showing the two pages with the text:
Bonus:
use page-break-inside: avoid;
to avoid page break inside
Contact me: Hung, Chien-Hsiang (chienhsiang-hung.github.io)