我正在开发一个简单的应用程序,用于在Swift for iOS中创建发票。 为此,我有一个带表和行的简单模板HTML(td / tr)。
我想将此HTML模板转换为多页PDF。由于UIPagePrintRenderer,它的工作方式就像一个魅力,但有些行在两个页面上重复,或者在两页上剪切了行。
我试图添加css" page-break"在我的模板上。当我在网络浏览器上打印模板时,我有一个很好的位置。
但是,当我将HTML导出为PDF时(感谢UIPagePrintRenderer),CSS样式没有应用于PDF文档,我的元素也是重复的。
我正在寻找将HTML转换为PDF的更好解决方案。有人遇到过类似的问题吗?
更新:
感谢回复人员,下面有关于问题和我的代码的更多信息。
首先,这是我将HTML字符串转换为PDF文件的功能。
func createPDF(formatter: UIViewPrintFormatter) -> String {
let render = CustomPrintRenderer()
render.addPrintFormatter(formatter, startingAtPageAt: 0)
formatter.maximumContentHeight = 605.0
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, CGRect.zero, nil)
for i in 0...render.numberOfPages {
UIGraphicsBeginPDFPage()
if(i != 0) {
render.setupAfterFirstPage()
}
render.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
}
UIGraphicsEndPDFContext()
pdfFilename = "\(AppDelegate().getDocDir())/Invoice-\(invoiceNumber!).pdf"
pdfData.write(toFile: pdfFilename, atomically: true)
return pdfFilename
}
其次,这是指定打印区域的CustomPrintRenderer()类。
class CustomPrintRenderer: UIPrintPageRenderer {
// A4 Gabarit
let A4PageWidth: CGFloat = 595.2
let A4PageHeight: CGFloat = 841.8
let topPadding: CGFloat = 50.0
let bottomPadding: CGFloat = 100.0
let pageInset: CGFloat = 42.5
//let leftPadding: CGFloat = 100.0
//let rightPadding: CGFloat = 100.0
override init() {
super.init()
initFrame()
}
func initFrame() {
// Specify the frame of the A4 page.
let pageFrame = CGRect(x: 0.0, y: 0.0, width: A4PageWidth, height: A4PageHeight)
let printable = CGRect(x: 0.0, y: -topPadding, width : A4PageWidth, height: A4PageHeight - topPadding).insetBy(dx: pageInset, dy: pageInset)
self.setValue(NSValue(cgRect: pageFrame), forKey: "paperRect")
self.setValue(NSValue(cgRect: printable), forKey: "printableRect")
}
func setupAfterFirstPage() {
let printable = CGRect(x: 0.0, y: topPadding, width : A4PageWidth, height: A4PageHeight - topPadding - bottomPadding).insetBy(dx: pageInset, dy: pageInset)
self.setValue(NSValue(cgRect: printable), forKey: "printableRect")
}
}
这是我的发票转换为PDF。 您可以在此屏幕截图中看到我的项目被裁剪。 所以,感谢"分页" css或其他方式的风格,如果元素不能完全放在当前页面上,我想在下一页显示一个项目。
更新2:
这是我的HTML模板:
主页'发票 - 发票
body {
max-width:90%;
margin:auto;
padding:30px;
font-size:16px;
line-height:24px;
font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
color:#485C74;
}
/*@media print
{
table { page-break-after:auto; }
tr.items { page-break-inside:avoid; page-break-after:auto; }
td.items { page-break-inside:avoid; page-break-after:auto; }
thead { display:table-header-group; }
tfoot { display:table-footer-group; }
}*/
/*@page {
size: A4;
margin: 0;
}
@media print {
html, body {
width: 210mm;
height: 297mm;
}
}*/
.middle {
width: 50%;
}
.invoice-box table td{
padding:5px;
vertical-align:top;
}
.logo-images img {
width:100%;
max-width:300px;
max-height:150px;
}
.invoice-box .left-pos {
text-align: left;
}
.invoice-box .center-pos {
text-align: center;
}
.invoice-box .right-pos {
text-align: right;
}
.invoice-box table thead.heading td{
background:#fab800;
border-bottom:1px solid #485C74;
font-weight:bold;
}
.invoice-box table{
width:100%;
line-height:inherit;
text-align:left;
}
.invoice-box table tr.top table td{
padding-bottom:20px;
}
.invoice-box table tr.top table td.title{
font-size:45px;
line-height:45px;
color:#485C74;
}
.invoice-box table tr.information table td{
padding-bottom:40px;
}
.invoice-box table tr.details td{
padding-bottom:20px;
}
.invoice-box table tr.item td, .invoice-box table tr.service td{
border-bottom:1px solid #eee;
}
.invoice-box table tr.item.last td, .invoice-box table tr.service.last td{
border-bottom:none;
}
.invoice-box .items-last, .invoice-box .services-last{
border-top:2px solid #485C74;
font-weight:bold;
}
footer {
text-align: center;
}
@media only screen and (max-width: 600px) {
.invoice-box table tr.top table td{
width:100%;
display:block;
text-align:center;
}
.invoice-box table tr.information table td{
width:100%;
display:block;
text-align:center;
}
}
</style>
</head>
<body>
<div class="invoice-box">
<table cellpadding="0" cellspacing="0">
<tbody>
<!-- Header Top section -->
<tr class="top">
<td colspan="5">
<table>
<tbody>
<tr>
<td class="logo-images"> <img src="data:image/png;base64, #LOGO_USER#"> </td>
<td class="right-pos">
Invoice : ##INVOICE_NUMBER#
<br>
Date : #INVOICE_DATE#
<br>
Due Date : #DUE_DATE#
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<!-- Payment section -->
<!-- Informations section -->
<tr class="information">
<td colspan="5">
<table>
<tbody>
<tr>
<td class="middle left-pos"> #SENDER_INFO# </td>
<td class="middle right-pos"> #RECIPIENT_INFO# </td>
</tr>
</tbody>
</table>
</td>
</tr>
<!-- Informations section -->
</tbody>
</table>
</div>
<div class="invoice-box">
<table cellpadding="0" cellspacing="0">
<tbody>
<!-- Payment section -->
<thead class="heading">
<td> Payment Method </td>
</thead>
<tr class="details">
<td class="left-pos"> Payment desired : #PAYMENT_METHOD# <br>
A deposit of #PAYMENT_PERCENT# must be paid when signing "good for the agreement" of this invoice, is #PAYMENT_PERCENT_PRICE#.
</td>
</tr>
</tbody>
</table>
</div>
<div class="invoice-box">
<table cellpadding="0" cellspacing="0">
<tbody>
<!-- Items section -->
<thead class="heading">
<td class="left-pos"> Item / Description </td>
<td class="center-pos"> Reference </td>
<td class="center-pos"> Quantity </td>
<td class="center-pos"> Unit cost </td>
<td class="right-pos"> Total Price (excl. tax)</td>
</thead>
#ITEMS#
<tr class="total">
<td></td>
<td></td>
<td></td>
<td></td>
<td class="right-pos items-last">
Subtotal (excl. tax) : #TOTAL_AMOUNT_HT#
<br>
Sales Tax (#VAT_RAT#) : #VAT_PRICE#
<br>
<br>
Total (incl. tax) : #TOTAL_AMOUNT_TTC#
</td>
</tr>
<!-- Items section -->
</tbody>
</table>
</div>
<footer>
<div class="footer_content">
<hr>
<p>Invoice powered By </p>
<div class="logo-images"> <img src="data:image/png;base64, #LOGO_FOOTER#"> </div>
</div>
</footer>
</body>
</html>
single_item.html:
<tr class="item">
<td class="left-pos">#ITEM_NAME# <br> #ITEM_DESC#</td>
<td class="center-pos">#ITEM_REF#</td>
<td class="center-pos">#ITEM_QUANTITY#</td>
<td class="center-pos">#ITEM_UNIT_COST#</td>
<td class="right-pos">#ITEM_TOTAL_PRICE#</td>
</tr>
last_item.html:
<tr class="item last">
<td class="left-pos">#ITEM_NAME# <br> #ITEM_DESC#</td>
<td class="center-pos">#ITEM_REF#</td>
<td class="center-pos">#ITEM_QUANTITY#</td>
<td class="center-pos">#ITEM_UNIT_COST#</td>
<td class="right-pos">#ITEM_TOTAL_PRICE#</td>
</tr>
更新3:
当我在我的&#34;项目&#34;上添加此代码时class,这些项目有一个很好的分页符,但显示不好。但是whitout&#34;显示:阻止;&#34;仍然不起作用:
.item {
display:block;
page-break-inside:avoid;
page-break-after: auto;
}