资讯动态

Electron PrintToPDFOptions 完全指南:用 webContents.printToPDF() 将网页打印为 PDF

发布时间:2026/9/7 4:19:25 来源:尧图企业网站定制
Electron PrintToPDFOptions 完全指南用 webContents.printToPDF() 将网页打印为 PDF【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electronElectron 的printToPDF()是主进程中把渲染进程当前网页转换为 PDF 二进制数据的核心能力其全部行为由PrintToPDFOptions对象驱动从纸张大小、页边距到页眉页脚模板均可精细控制。本文以 PrintToPDFOptions 结构文档 为主体逐条讲解每个选项的类型、默认值与语义并结合 lib/browser/print-to-pdf.ts 的源码实现与 spec/api-web-contents-spec.ts 中的测试用例说明选项如何被校验、转换并下发给 Chromium 打印管线以及并发调用时的队列保护机制。API 入口printToPDF(options) 的调用位置PrintToPDFOptions是以下两个 API 的入参结构两者共享同一份选项翻译与任务排队逻辑见 lib/browser/print-to-pdf.ts 顶部注释contents.printToPDF(options)定义在 WebContents 文档 的 printToPDF 小节通过 lib/browser/api/web-contents.ts 挂载到原型上frame.printToPDF(options)定义在 WebFrameMain 文档实现见 lib/browser/api/web-frame-main.ts。返回值均为PromiseBufferresolve 的值即完整的 PDF 文件数据可直接fs.writeFile落盘。官方文档中的最小示例const { app, BrowserWindow } require(electron) const fs require(node:fs) const os require(node:os) const path require(node:path) app.whenReady().then(() { const win new BrowserWindow() win.loadURL(https://example.com) win.webContents.on(did-finish-load, () { // 使用默认打印选项 const pdfPath path.join(os.homedir(), Desktop, temp.pdf) win.webContents.printToPDF({}).then(data { fs.writeFile(pdfPath, data, (error) { if (error) throw error console.log(Wrote PDF successfully to ${pdfPath}) }) }).catch(error { console.log(Failed to write PDF to ${pdfPath}: , error) }) }) })一个需要注意的文档声明如果网页使用了pageCSS at-rulelandscape选项会被忽略。也就是说 CSS 的页面方向优先级高于该布尔选项这在给已有打印样式的设计稿生成 PDF 时要特别留意。PrintToPDFOptions 属性总览以下表格完整继承自 print-to-pdf-options.md默认值与类型校验均以源码为准属性类型默认值说明landscapebooleanfalse纸张方向true横向false纵向displayHeaderFooterbooleanfalse是否显示页眉和页脚printBackgroundbooleanfalse是否打印背景图形scalenumber1网页渲染缩放比例pageSizestring | SizeLetter指定生成 PDF 的纸张大小取A0–A6、Legal、Letter、Tabloid、Ledger之一或包含width/height单位英寸的对象marginsPrintToPDFMargins{}各边 0.4 英寸页边距单位英寸pageRangesstring打印全部页面要打印的页码范围如1-5, 8, 11-13headerTemplatestring页眉 HTML 模板footerTemplatestring页脚 HTML 模板格式同headerTemplatepreferCSSPageSizebooleanfalse是否优先采用 CSS 定义的页面大小为false时内容会被缩放以适配纸张generateTaggedPDFboolean实验性false是否生成带标记可无障碍访问的 PDFgenerateDocumentOutlineboolean实验性false是否根据内容标题生成 PDF 文档大纲默认值并非凭空而来lib/browser/print-to-pdf.ts 中的printSettings构造段逐项写明了回退链landscape ?? false、displayHeaderFooter ?? false、headerTemplate ?? 、scale ?? 1.0、pageRanges ?? 、四个边距统一?? 0.4再叠加parsePageSize(options.pageSize ?? letter)的结果。源码还有一层文档未强调的防御每个选项都会经过checkTypeL20-L27做运行时类型断言类型不符会抛出TypeError例如margins must be an object。测试文件 spec/api-web-contents-spec.ts 对此有专门用例逐项传入landscape: []、scale: not-a-number、pageSize: IAmAPageSize、margins: terrible等错误类型并断言全部被 reject——用例注释解释了动机“These will hard crash in Chromium unless we type-check”即不校验会让 Chromium 直接崩溃Electron 层的前置类型检查把崩溃转化为可捕获的 Promise rejection。pageSize纸张大小的解析与全部取值pageSize是约束最多的选项。parsePageSize 定义了三种情况字符串形式按小写匹配内置纸张表paperFormatsL6-L18命中则展开为paperWidth/paperHeight英寸未命中抛Invalid pageSize ${pageSize}错误格式宽英寸高英寸Letter8.511Legal8.514Tabloid1117Ledger1711A033.146.8A123.433.1A216.5423.4A311.716.54A48.2711.7A55.838.27A64.135.83对象形式{ width, height }两个字段都必须是 number否则抛TypeError: width and height properties are required for pageSize其他类型抛TypeError: pageSize must be a string or an object。测试 spec/api-web-contents-spec.ts 的with custom page sizes用例对上述全部 11 种格式逐一生成 PDF并用 pdf.js 解析页面view数组[top, left, width, height]单位 PDF point除以 72 换算回英寸断言与上表数值在 0.01 英寸误差内一致——这是“选项表”与“实际输出”之间的端到端核对。marginsPrintToPDFMargins 与越界校验margins 结构 包含四个可选字段单位均为英寸topnumber可选- 顶部边距默认 1cm约 0.4 英寸bottomnumber可选- 底部边距默认同上leftnumber可选- 左侧边距默认同上rightnumber可选- 右侧边距默认同上除了类型检查lib/browser/print-to-pdf.ts 还做物理合理性校验top bottom方向上要求top和bottom各自不超过纸张高度left/right各自不超过纸张宽度任一违反即抛margins must be less than or equal to pageSize。测试 rejects when margins exceed physical page size 用pageSize: Letter配top: 100, bottom: 100精确复现了这条错误信息。// A4 纵向 自定义边距 页眉页脚 背景打印 const data await win.webContents.printToPDF({ pageSize: A4, landscape: false, printBackground: true, scale: 1, margins: { top: 0.5, bottom: 0.5, left: 0.6, right: 0.6 }, displayHeaderFooter: true, headerTemplate: span classtitle/span, footerTemplate: 第 span classpageNumber/span 页 / 共 span classtotalPages/span 页 })pageRanges页码范围筛选pageRanges为字符串格式形如1-5, 8, 11-13默认空字符串表示打印全部页面。两点行为值得注意均有测试佐证无效范围会 reject传入pageRanges: 999超出实际页数的调用会失败L4599失败后可恢复recovers after a prior call fails with an invalid page range 用例先触发失败再立即发起一次printToPDF({})断言后续调用正常返回单页 PDF——说明一次失败不会污染底层打印状态范围数量正确对多页 fixturespec/fixtures/api/print-to-pdf-large.html传入pageRanges: 1-3后解析出的numPages恰为 3L4582-L4594。headerTemplate / footerTemplate页眉页脚模板模板生效的前置条件是displayHeaderFooter: true。两者均为合法 HTML 片段通过特定 class 名注入打印时的动态值class注入内容date格式化后的打印日期title文档标题url文档位置URLpageNumber当前页码totalPages文档总页数例如span classtitle/span会被替换为包含文档标题的 span。测试 with custom header and footer 传入divIm a PDF header/div与divIm a PDF footer/div再用 pdf.js 提取全文断言两段文本都出现在 PDF 内容流中。方向、背景、缩放与 CSS 页面大小landscape: true使输出宽高反转。in landscape mode 用例直接断言width height。再次提醒若页面 CSS 定义了page规则此选项会被忽略。printBackground: true才输出背景色/背景图这与浏览器打印对话框的“背景图形”复选框语义一致。scale是网页渲染缩放比例默认 1必须是 numberscale: not-a-number会被 reject。preferCSSPageSize默认false此时内容会被缩放以适配纸张设为true时优先采用 CSS 定义的页面大小。该选项主要服务page已定义尺寸/边距的打印友好页面。实验性选项generateTaggedPDF 与 generateDocumentOutline文档将两者标记为ExperimentalgenerateTaggedPDF生成带标记tagged即可无障碍访问的 PDF文档明确提示该属性处于实验阶段生成的 PDF 可能不完全符合 PDF/UA 与 WCAG 标准generateDocumentOutline根据内容标题生成 PDF 文档大纲。测试 can generate tag data for PDFs 验证了启用后的实际产物pdf.js 读出的markInfo深度等于{ Marked: true, UserProperties: false, Suspects: false }而 does not tag PDFs by default 用例确认默认输出markInfo为 null即默认 PDF 不带标记结构。源码级执行流程从选项校验到打印任务排队printToPDF() 的完整执行链如下类型断言checkType逐个校验各选项margins缺省按空对象处理纸张解析parsePageSize将字符串或对象统一展开为paperWidth/paperHeight边距越界检查四边分别不得超过对应方向的纸张尺寸构造 printSettings按默认值回填后附加自增的requestIDnextRequestId交给底层绑定target._printToPDF。若该绑定不存在抛Printing feature is disabled——测试套件正是用features.isPrintingEnabled()守卫整个 printToPDF 测试块spec/api-web-contents-spec.ts#L4422说明该能力在构建中可被整体裁剪按帧树排队同一帧树frame tree内的并发 PDF 任务在渲染进程会互相冲突源码用一个以frameTreeNodeId为键的Map做串行化L60-L112新任务catch(() {})掉前一个任务的错误后串联执行完成后清理队列项。选择frameTreeNodeId而非对象身份做键是因为它跨导航稳定mainFrame/top在窗口销毁过程中可能为 null此时统一落入-1桶。不同webContents之间的打印可以并行。对应测试有两条稳定性用例does not crash when called multiple times in parallel同一 webContents 同时发起 3 次与 in sequence均断言三次返回非空Buffer。此外测试覆盖了若干边缘场景可作为能力边界的可靠依据iframe 打印同源 iframe 内容可以被打印L4614-L4620跨域 iframe 在 Linux 上因 OOPIF 崩溃问题暂被禁用该用例带平台条件process.platform ! linuxL4622-L4638直接打印现有 PDF 文件加载file://的 PDF 后需先等待-pdf-ready-to-print事件再调用printToPDF({})L4652-L4661webview 场景同理。输出结果的验证方式测试基础设施 spec/lib/pdf-helpers.ts 展示了官方如何验证printToPDF的产物把 Buffer 写入临时目录再 fork 一个 Node 子进程运行spec/fixtures/api/pdf-reader.mjs基于 pdf.js解析 PDF返回页数、页面view、markInfo与文本内容等 JSON 信息。这个“Buffer → pdf.js 解析 → 断言元数据”的模式可以直接搬到自己的集成测试里const data await w.webContents.printToPDF({ pageSize: A4 }) // data 是 Buffer先落盘再用任意 PDF 解析器核对 // 页面尺寸 view[2] / 72 英寸标记状态看 markInfo小结PrintToPDFOptions的十二个属性在 print-to-pdf-options.md 中给出了完整契约而 lib/browser/print-to-pdf.ts 保证了这份契约在运行期被严格执行类型错误被转化为可捕获的异常、纸张大小被解析为英寸尺寸、页边距被限制在纸张物理范围内、并发任务被按帧树串行化。开发者只需按“纸张 → 边距 → 页眉页脚 → 范围筛选”的顺序配置选项即可获得一份可复现、可测试的 PDF 输出对结果质量有疑问时参照 spec/lib/pdf-helpers.ts 的 pdf.js 解析方式即可对输出做量化断言。【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价