如何构建 Web Page to PDF 转换器并保持理智

发布: (2026年2月21日 GMT+8 20:58)
7 分钟阅读
原文: Dev.to

抱歉,我需要您提供要翻译的具体文本内容(除源码链接外的正文),才能为您进行简体中文翻译。请把文章的其余部分粘贴在这里,我会按照要求保留格式并完成翻译。

将文章保存为 PDF – 仅限纯文本

你是否曾想把文章保存为 PDF 而不带所有额外的杂乱内容——只保留干净、可选中的文本?
或者你只需要页面的特定部分,并希望所有内容在一页长页面上显示,且没有分页?

我也有同样的需求,于是自己实现了一个解决方案,并将其做成了浏览器扩展。

标准的 CTRL + P 有什么问题?

当我把内容保存为 PDF 时,我希望它看起来 完全 与屏幕上一致:

  • 可点击的链接
  • 整个文档在单个长页面上(没有分页)

CTRL+P 做不到这些。它是为纸质打印设计的,根本不支持上述其他需求。

可用模式在扩展中

1. 完整页面

完整页面模式

  • 完全保存页面的当前显示效果。
  • 文本仍然可选,链接仍然可点击。
  • 不是带 OCR 文本的图片——它是真正的 PDF,包含真实文本和真实链接。

2. 导出页面元素

导出页面元素模式

  • 在页面上选择特定元素,仅导出元素。
  • 方便保存单篇文章、代码块或其他任何元素。
  • 我经常在提交 Google 表单时使用此模式,以便保留填写数据的副本。

3. 文章

最有趣的模式之一。它可以以阅读友好视图保存博客文章——页面上没有其他内容,只有文章本身。

在此模式下,我确保:

  • 代码块能够正确换行。
  • “ 标签被展开。

因此整篇文章内容都会出现在 PDF 中。

4. 删除元素

删除元素模式

  • 点击页面上的任意元素并将其删除(例如侧边栏、菜单、广告)。
  • 如果不小心删除了重要内容,按 CTRL + Z 撤销。

5. 导出 ChatGPT、DeepSeek 和 Gemini 的聊天记录

由于 AI 公司未提供聊天记录的 PDF 导出功能,我在扩展中加入了此功能。一键即可保存当前打开的对话。

布局选项(所有模式均可用)

  • 单页 PDF – 连续滚动,无分页。
  • 多页 PDF – 适合打印。

您还可以将页面尺寸调整为匹配屏幕或标准格式,如 A4A5 等。

如何不让自己抓狂

布局变体太多

保存网站为 PDF 很困难。无法兼顾每一种布局变体——总会有东西出错。

我尝试逐站点修复问题,但很快就变成了对风车的无意义斗争。现在我只为大型平台(例如 Notion)添加特殊修复。

原子化 CSS

大规模采用原子化 CSS 框架(如 Tailwind)让可靠的元素选择变得困难。

  • 导出 ChatGPT 对话需要大量工作和复杂的选择器才能抓取对话框元素。
  • 使用 Claude Code 时,我因为布局放弃了。
  • Gemini 是最容易的——它的类名实际上是可读的。

懒加载

懒加载的图片是另一大痛点。对于包含大量图片的长页面,我使用以下简单方法确保所有图片在生成 PDF 前加载完毕:

for (const img of document.querySelectorAll('img')) {
  img.scrollIntoView();          // trigger loading
  await new Promise(r => setTimeout(r, 100)); // wait ~100 ms
}

如果你有更优雅的方案,欢迎在评论中分享。

恢复页面样式

导出页面元素模式会隐藏页面上除选定元素之外的所有内容,然后在不重新加载页面的情况下恢复所有样式。

重新加载不是选项——想象一下填写了一个长表单,点击“导出”,页面却刷新了。那种愤怒是真实的。我也经历过。

没有文档

渲染最终 PDF 本身就是一个故事。没有好用的库来完成这项任务。

  • Mozilla 的 PDF.js 包含 PDFViewer,听起来很棒——但基本没有文档。
  • 只能通过阅读源码和 GitHub issue 来摸索。
  • 有大量 issue 请求文档,但 Mozilla 并不打算提供。也算公平——不过还是谢谢这个库。

引擎内部

以下是我主要使用的工具:

  • WXT.dev – 用于构建浏览器扩展的框架。在我看来,它是目前最好的选择:快速的 HMR、独立的测试浏览器、极佳的开发速度。
  • PDFViewer (PDF.js) – 用于渲染 PDF。

(原文中其余列表被截断。)

PDF 生成选项

从网页生成 PDF 可能会比较棘手。以下是一些最可靠的方法:

  • Chrome 调试器Chrome DevTools Protocol (Page)
    该方法使用 Chrome 调试器将页面转换为 PDF。乍看可能有点奇怪,但它能生成最高质量的 PDF。

接下来是什么?

我正在不断添加与流行网站的集成。

例如,我最近推出了 一键保存 Reddit 帖子

该网络服务的功能不如扩展程序丰富,但它可以在移动设备上使用。

0 浏览
Back to Blog

相关文章

阅读更多 »

Undefined 与 Not Defined

Undefined undefined 是 JavaScript 中的一个特殊关键字。它表示变量已经在内存中存在,但尚未被赋值。在创建阶段…