nodejs 生成pdf
https://pptr.dev/
https://github.com/puppeteer/puppeteer
pnpm add puppeteer # Downloads compatible Chrome during installation.
pnpm add puppeteer-core # Alternatively, install as a library, without downloading Chrome.
const fs = require('fs');
const http = require('http');
const puppeteer = require('puppeteer');
async function getPdf(res) {
// 启动无头浏览器
const browser = await puppeteer.launch({ headless: true });
// this.ctx.logger.info('browser')
// 打开一个新tab
const page = await browser.newPage();
// 设置窗口大小
await page.setViewport({
width: 1920,
height: 1080
})
// this.ctx.logger.info('page')
// 跳转到指定页面
// const target = 'https://juejin.cn/post/7139047512085626911';
const target = 'https://pnglog.com/';
await page.goto(target, {waitUntil: 'networkidle0'});
// this.ctx.logger.info('page2')
// 页眉模板(图片使用base64,此处的src的base64为占位值)
const headerTemplate = `<div
style="width: calc(100% - 28px); margin-top: -13px; font-size:8px;border-bottom:2px solid #e1dafb;padding:6px 14px;display: flex; justify-content: space-between; align-items:center;">
<span style="color: #9a7ff7; font-size: 12px; font-family: my-font;">张博的模板</span>
<img style="width: 80px; height: auto;" src="data:image/png;base64,iVBORw0KGgoAAAxxxxxx" />
</div>`
// 页脚模板(pageNumber处会自动注入当前页码)
const footerTemplate = `<div
style="width:calc(100% - 28px);margin-bottom: -20px; font-size:8px; padding:15px 14px;display: flex; justify-content: space-between; ">
<span style="color: #9a7ff7; font-size: 10px;">蒲公英绩效</span>
<span style="color: #9a7ff7; font-size: 13px;" class="pageNumber"></span>
</div>`;
// 拿到PDF文件流
const pdf = await page.pdf({
headerTemplate,
footerTemplate,
margin: {
top: 50,
bottom: 50,
left: 0,
right: 0
},
displayHeaderFooter: true,
printBackground: true,
});
await browser.close();
fs.writeFileSync('test.pdf', pdf); // 保存到本地文件
res.setHeader('Content-Type','application/pdf');
res.setHeader('Content-Length', pdf.length );
res.end(pdf);
}
const port = 8080;
const server = http.createServer((req, res) => {
// console.log(res)
getPdf(res)
});
server.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
node server.js
// 图片被截断问题
// page-break-after : auto | always | avoid | left | right
// page-break-before : auto | always | avoid | left | right
// page-break-inside : auto | avoid
// 需要处理的元素样式添加:
// page-break-inside:avoid
// page-break-before: always
// 一般采用向上插入空白占位进行分页以避免元素被分页截断
发布:2025-02-17 14:48:03
修改:2025-02-17 14:52:06