[英]HTML content to PDF not adding page if it is overflowing - jsPDF
[英]Converting html to pdf: how to dynamically add pages to pdf when html content is overflowing? (dynamic multiple page pdf)
我正在使用 Handlebars 和 Puppeteer 将 html 编译成动态.pdf
发票。 有时发票会变得相当大(2-3 页)。 结果,溢出的 html 内容被截断,请参见此图:
我已经用我的所有代码和问题制作了一个 github 回购协议,如果您有兴趣可以在这里查看(在read.me
中运行项目的说明)。
所以我试图解决这个问题的方法是,在 Handlebars 渲染我的模板之后,我启动一个带有 puppeteer 的无头浏览器,并将渲染的 html 设置为页面。
//renderTemplate is a function that reads the .hbs file and compiles the template to html.
const html = renderTemplate(data)
await page.setContent(html, {
waitUntil: 'load'
})
然后我跟踪高度:
const heightTracker = await page.$(".height-tracker");
const heightTrackerDimensions = await heightTracker.boundingBox()
如果这个高度超过,比如说 1100,那么必须添加一个新页面并且我的订单数组中的最后item
必须从 html 中剪切并粘贴到新页面。 我能想到的最好的是这样的:
if (heightTrackerDimensions.height > 1100) {
let pageIndex = 0;
let height = 0;
let sections = await page.$$(".item");
for (let i = 0; i < sections.length; i++) {
const sectionDimensions = await sections[i].boundingBox();
if (height + sectionDimensions.height > 1100) {
pageIndex++;
console.log(i)
await page.evaluate(() => {
let sections = document.querySelectorAll(`.item`)
const page = document.querySelector('.page1')
page.insertAdjacentHTML('afterend', `
<div style="page-break-after: always;"></div>
<div class="invoice page2">
<div class="invoice-inner">
<div class="invoice-body">
<div class="main-column">
<div class="height-tracker">
${sections[i].innerHTML}
</div>
</div>
<div class="secondary-column">
</div>
</div>
</div>
</div>
`
)
sections[i].remove()
});
height += sectionDimensions.height
} else {
height += sectionDimensions.height
}
}
}
但这只是效果不佳,一旦有更多项目从第 1 页溢出时就会中断。也许我过于复杂了。 也许有更简单的方法来实现相同的目标?
我只是为这个问题而烦恼。 我怎样才能使溢出的 html 内容自动添加到具有适当边距和填充的新 pdf 页面? 我还有哪些其他选择? 我不可能是唯一一个使用 Puppeteer 处理多页 pdf 的人......
我遇到了与 PDF 代相同的问题,尽管不完全是在相同的上下文中。
我玩过你的代码,并做了一些改变,主要是为了让 Puppeteer 自己创建需要的页面,希望能简化事情:
async function printPDF() {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
const orders = [
{ item: "Completely new website design to your company style", price: "$300" },
{ item: "Conversions optimalization and management of conversions", price: "$300" },
{ item: "Implementation of content management system - Wordpress", price: "$300" },
{ item: "Installation of Premium Wordpress Theme yearly renewed (Divi)", price: "$300" },
{ item: "Responsive desktop / mobile / tablet", price: "$300" },
{ item: "Loadspeed optimized", price: "$300" },
{ item: "Free service contract (1 year)", price: "$300" },
{ item: "Media Manager", price: "$300" },
{ item: "Google Maps", price: "$300" },
{ item: "Contactforms", price: "$300" },
{ item: "Search Engine indexation", price: "$300" },
{ item: "Google Analytics / Google search console implementation", price: "$300" },
];
const data = {
invoiceNumber: "123123123",
company: "Acme Corp",
orders: orders,
total: orders.reduce((sum, order) => sum + (+order.price.replace("$", "")) , 0)
}
page.on('console', consoleObj => console.log(consoleObj.text()));
const html = renderTemplate(data)
await page.emulateMediaType('print');
await page.setContent(html, {
waitUntil: 'load'
})
const pdf = await page.pdf({
format: 'A4',
printBackground: true,
margin: {
top: "10mm",
right: "10mm",
bottom: "10mm",
left: "10mm"
},
format: "A4"
})
await browser.close();
return pdf
}
我还在 template.hbs 中更新了 the.invoice class(只是为了删除 height 和 max-height 项目):
.invoice {
background-color: white;
position: relative;
background-size: cover;
display: flex;
flex-direction: column;
width: 210mm;
/*height: 297mm; */
min-width: 210mm;
min-height: 297mm;
max-width: 210mm;
/*max-height: 297mm; */
font-variant-ligatures: none !important;
-webkit-font-smoothing: antialiased !important;
text-rendering: geometricprecision !important;
overflow: hidden;
background-repeat: no-repeat;
background-position: center center;
}
以及总金额:
<tr class="total">
<td></td>
<td>
Total: ${{ total }}
</td>
</tr>
一个例子在这里: https://dropmefiles.com/xRuqY
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.