利用puppeteer将网页保存为pdf 日期:2025-06-27 人气:0 有一个项目其中一个需求就是利用后台内容生成pdf,感谢deepseek给我提供了思路,我按照它的提示利用html成功的将内容转换成了pdf 将网页保存为pdf分为以下几步 - 制定网页内容,控制每页的内容,写样式分页 - 启动生成pdf的服务 - 将内容传给服务生成pdf 下面分别说明每步的实现步骤 ### 网页内容 一个网页要想在pdf中显示正常,关键是控制好大小和字体,而且要精确的计算每个字的大小,一行或者一列占几个字,每页显示几行几列。每个字体所占大小是不一样的,中文的话推荐使用`微软雅黑`。 例如一篇文章,做数据分页可以在服务端分好传给前端直接循环显示,也可以在前端利用脚本拆分内容。 样式分页可以照搬,如下为A4纸样式 - 页面大小: ``` width: 595px; height: 842px; ``` - 内容大小,尽管在页面上显示完美可能到了pdf中会发现并不合适,这是因为分辨率的问题,而这个问题我的做法是使用不同的单位,页面中显示的时候用`px`,而生成pdf的时候用`pt`,将所有用到px的地方换成pt就可以 - 分页问题,你为每个div设置了合适的大小,但是发现生成pdf时并不是每个div占一页,解决这个问题需要在生成pdf的时候增加`page break`样式 - 颜色问题,如果你使用了var,可能生成pdf的时候发现颜色没有,解决这个问题需要在`:root`中声明 完整的样式如下: ``` @media print { .page-break { page-break-after: always; break-after: page; } /* 设置页面尺寸 */ @page { size: A4; margin: 0; } :root { --text-basic-color: #222b45; --background-basic-color-2: #f7f9fc; --color-basic-transparent-focus-border: #8f9bb3; } body { width: 595pt; height: 842pt; margin: 0; } } ``` ### pdf服务 推荐使用nodejs的puppeteer来生成pdf 在linux中安装puppeteer的时候注意,因为需要安装浏览器,而linux默认没有图形界面,所以在安装的时候要添加跳过安装浏览器的参数,然后手动安装浏览器 安装完成之后用node启动如下脚本: ``` // server/pdf-service.ts import express from 'express'; import puppeteer from 'puppeteer'; const app = express(); const port = 3000; app.use(express.json({ limit: '50mb' })); app.post('/generate-pdf', async (req, res) => { try { const { html, options } = req.body; const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); const page = await browser.newPage(); await page.setContent(html, { waitUntil: 'networkidle0' }); // await page.setViewport({ width: 595, height: 842 }); const pdf = await page.pdf({ format: 'A4', printBackground: true, preferCSSPageSize: true, // Uses @page size ...options }); await browser.close(); res.contentType('application/pdf'); res.send(pdf); } catch (error) { console.error('PDF生成失败:', error); res.status(500).send('PDF生成失败'); } }); app.listen(port, () => { console.log(`PDF服务运行在 http://localhost:${port}`); }); ``` 注意启动的时候`headless`一定要设置为true,因为我们用的是无图形模式。 但是当你运行的时候会遇到各种各样依赖缺失的问题,不要灰心一个一个安装就是了。分享一个网友整理的[问题汇总](https://blog.csdn.net/weixin_44250886/article/details/128919402),我安装的时候基本也是遇到的这些问题。 字体问题,当你所有依赖安装完成并成功生成了pdf之后,发现中文不显示,这是因为你的系统没有安装中文字体,将windows上的`微软雅黑`拷贝到linux中,刷新一下字体库即可。 ### 调用服务 程序调用pdf服务的时候需要注意options参数,format为`A4`,scale为`2`,如果你网页在pdf中大小显示不合适的话,调整scale参数,我贴一个ts的方法作为参考 ``` /** * 生成pdf */ async generatePdf() { const html = this.pdfContent.nativeElement.innerHTML; const styleSheets = Array.from(document.styleSheets) .map((sheet: CSSStyleSheet) => { try { return Array.from(sheet.cssRules) .map(rule => rule.cssText) .join(''); } catch (e) { console.warn('Could not read stylesheet:', sheet.href); return ''; } }) .join(''); const options = { format: 'A4', scale: 2, // 分辨率,72pt = 1in }; const str_content = ` <!DOCTYPE html> <html> <head> <style> @media print { .page-break { page-break-after: always; break-after: page; } /* 设置页面尺寸 */ @page { size: A4; margin: 0; } :root { --text-basic-color: #222b45; --background-basic-color-2: #f7f9fc; --color-basic-transparent-focus-border: #8f9bb3; } body { width: 595pt; height: 842pt; margin: 0; } } <style> ${styleSheets} </style> </head> <body> ${html} </body> </html> `; this.provider.generatePdf(str_content, options).subscribe(blob => { downLoadFile(blob, this.pdfName + '.pdf'); // 下载文件 this.downloading = false; }); } ``` ### 鸣谢 - [csdn**weixin_44250886**](https://blog.csdn.net/weixin_44250886/article/details/128919402) 标签: 上一篇:vscode使用Community Server Connector运行JDK1.8项目报错 下一篇:一天二十四时辰表 随便看看 2025-07-04 vscode使用Community Server Connector运行JDK1.8项目报错 2025-07-03 vscode中为maven项目指定java版本 2025-06-27 利用puppeteer将网页保存为pdf 2025-06-27 一天二十四时辰表 2025-06-27 家谱中儿子和父母的关系有哪些? 留言