npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

webpage2pdf

v1.0.0

Published

Convert web pages to PDF - Command line tool and Node.js module

Readme

webpage2pdf

一个功能强大的工具,可以将网页、HTML 字符串、Buffer 或 Stream 转换为 PDF 文件。支持命令行函数调用两种使用方式,还支持流式输出多页面合并等高级功能。

安装

方式一:全局安装(推荐)

使用 npm:

npm install -g webpage2pdf

或使用 pnpm:

pnpm add -g webpage2pdf

之后可以直接使用:

webpage2pdf https://www.baidu.com

方式二:本地安装

使用 npm:

npm install webpage2pdf

# 使用 npx 运行
npx webpage2pdf https://www.baidu.com

或使用 pnpm:

pnpm add webpage2pdf

# 使用 pnpm exec 运行
pnpm exec webpage2pdf https://www.baidu.com

方式三:作为依赖安装

使用 npm:

npm install webpage2pdf --save

或使用 pnpm:

pnpm add webpage2pdf

使用方法

方式一:命令行使用

基本用法

# 将网页转换为 PDF(默认使用页面标题作为文件名)
webpage2pdf https://www.baidu.com
# 输出:./百度一下,你就知道_202512251539.pdf

# 指定输出路径
webpage2pdf https://www.baidu.com -o ./my-pdf.pdf

# 指定页面尺寸
webpage2pdf https://www.baidu.com -s A4_PRINT

# 等待更长时间(确保页面完全加载)
webpage2pdf https://www.baidu.com -w 5000

# 等待特定元素出现
webpage2pdf https://www.baidu.com --selector "button"

命令行选项

| 选项 | 简写 | 说明 | 默认值 | |------|------|------|--------| | --output | -o | 输出文件路径 | 使用页面标题(document.title) | | --size | -s | 页面尺寸(A4, A4_PRINT, A3, LETTER) | A4 | | --wait | -w | 等待时间(毫秒) | 3000 | | --selector | | 等待的选择器(如:button, #content) | 无 | | --header | | 自定义请求头(格式:key:value,可多次使用) | 无 |

方式二:函数调用

基本用法

const { generatePdf } = require('webpage2pdf');

// 基本使用
async function example() {
  const result = await generatePdf('https://www.baidu.com', './output.pdf');
  
  if (result.success) {
    console.log('PDF 生成成功:', result.path);
    console.log('文件大小:', result.size, 'bytes');
    console.log('页面标题:', result.title);
  } else {
    console.error('生成失败:', result.error);
  }
}

example();

高级用法

const { generatePdf, PAGE_SIZE_CONFIG, setVerbose } = require('webpage2pdf');

// 关闭详细日志输出(函数调用时推荐)
setVerbose(false);

async function advancedExample() {
  const result = await generatePdf('https://example.com', './output.pdf', {
    pageSize: 'A4_PRINT',        // 页面尺寸
    waitTime: 5000,              // 等待时间(毫秒)
    selector: '#content',         // 等待特定元素
    headers: {                   // 自定义请求头
      'Authorization': 'Bearer token',
      'X-Custom-Header': 'value'
    }
  });
  
  if (result.success) {
    console.log('成功:', result.path);
  }
}

advancedExample();

API 文档

generatePdf(input, outputPath, options)

将网页或 HTML 转换为 PDF。

参数:

  • input (string|string[]|Buffer|Readable, 必需) - 输入:
    • string - URL 或 HTML 字符串
    • string[] - URL 数组(多页面合并)
    • Buffer - HTML Buffer
    • Readable - HTML Stream
  • outputPath (string|null, 可选) - 输出文件路径
    • string - 保存到文件
    • null - 返回 Stream
  • options (object, 可选) - 配置选项
    • pageSize (string) - 页面尺寸,可选值:A4, A4_PRINT, A3, LETTER,默认:A4
    • waitTime (number) - 等待时间(毫秒),默认:3000
    • selector (string) - 等待的选择器(可选),默认:null
    • headers (object) - 自定义请求头(可选),默认:{}
    • margin (object) - 页边距,格式:{top, right, bottom, left},单位 mm,默认:{top: '0mm', right: '0mm', bottom: '0mm', left: '0mm'}
    • scale (number) - 缩放比例(0.1-2),默认:1
    • printBackground (boolean) - 是否打印背景,默认:true
    • ignore (string|RegExp|Array) - 要忽略的错误(字符串、正则或数组),默认:[]
    • debug (boolean) - 是否输出调试信息,默认:false

返回值:

{
  success: boolean,    // 是否成功
  path?: string,       // 输出文件路径(文件输出时)
  stream?: Readable,   // PDF Stream(流式输出时)
  size: number,       // 文件大小(字节)
  title?: string,      // 页面标题(URL 输入时)
  error?: string,      // 错误信息(失败时)
  ignored?: boolean   // 是否被忽略(错误被忽略时)
}
setVerbose(verbose)

设置是否输出详细日志。

参数:

  • verbose (boolean) - 是否输出日志,默认:true
PAGE_SIZE_CONFIG

页面尺寸配置对象,包含所有可用的页面尺寸。

示例

示例 1:转换公开网页

# 命令行
webpage2pdf https://www.example.com -o example.pdf
// 函数调用
const { generatePdf } = require('webpage2pdf');
await generatePdf('https://www.example.com', './example.pdf');

示例 2:转换需要认证的页面

# 命令行
webpage2pdf https://api.example.com/page \
  --header "Authorization:Bearer token" \
  -o authenticated.pdf
// 函数调用
const { generatePdf } = require('webpage2pdf');
await generatePdf('https://api.example.com/page', './authenticated.pdf', {
  headers: {
    'Authorization': 'Bearer token'
  }
});

示例 3:等待动态内容加载

# 命令行
webpage2pdf https://example.com/dynamic-page \
  --selector "#content" \
  -w 10000 \
  -o dynamic-page.pdf
// 函数调用
const { generatePdf } = require('webpage2pdf');
await generatePdf('https://example.com/dynamic-page', './dynamic-page.pdf', {
  selector: '#content',
  waitTime: 10000
});

示例 4:流式输出

// 函数调用 - 返回 Stream
const { generatePdf } = require('webpage2pdf');
const fs = require('fs');

const result = await generatePdf('https://example.com', null);
if (result.success) {
  result.stream.pipe(fs.createWriteStream('output.pdf'));
}

示例 5:HTML 字符串输入

const { generatePdf } = require('webpage2pdf');

const html = `
<html>
  <head><title>Test</title></head>
  <body><h1>Hello World</h1></body>
</html>
`;

const result = await generatePdf(html, './output.pdf');

示例 6:多页面合并

const { generatePdf } = require('webpage2pdf');

const urls = [
  'https://example.com/page1',
  'https://example.com/page2',
  'https://example.com/page3'
];

// 合并多个页面到一个 PDF
const result = await generatePdf(urls, './combined.pdf', {
  pageSize: 'A4',
  waitTime: 5000
});

注意:当前多页面合并使用简单的 Buffer 拼接方式,可能无法正确处理复杂的 PDF 结构。如果需要专业的 PDF 合并功能(如保留书签、目录等),建议:

  1. 使用 pdf-lib 等专业库自行实现合并逻辑
  2. 先分别生成各个 PDF,然后使用专业工具合并

示例 7:错误忽略

const { generatePdf } = require('webpage2pdf');

const result = await generatePdf('https://example.com', './output.pdf', {
  ignore: ['timeout', /网络错误/],  // 忽略特定错误
  debug: true  // 开启调试模式
});

示例 8:自定义边距和缩放

const { generatePdf } = require('webpage2pdf');

const result = await generatePdf('https://example.com', './output.pdf', {
  margin: { top: '20mm', right: '15mm', bottom: '20mm', left: '15mm' },
  scale: 0.9,              // 缩放 90%
  printBackground: true   // 打印背景
});

示例 9:批量转换

const { generatePdf, setVerbose } = require('webpage2pdf');

// 关闭详细日志
setVerbose(false);

const urls = [
  'https://example.com/page1',
  'https://example.com/page2',
  'https://example.com/page3'
];

async function batchConvert() {
  for (const url of urls) {
    const result = await generatePdf(url, `./${Date.now()}.pdf`);
    console.log(result.success ? '✓' : '✗', url);
  }
}

batchConvert();

支持的页面尺寸

  • A4: 210mm × 297mm(标准 A4)
  • A4_PRINT: 216mm × 291mm(A4 打印尺寸)
  • A3: 297mm × 420mm(A3)
  • LETTER: 8.5in × 11in(美国 Letter)

技术说明

  • 使用 Puppeteer 进行网页渲染和 PDF 生成
  • 优先使用系统 Chrome(如果可用),否则使用 Puppeteer 内置的 Chromium
  • 支持多种输入类型:URL、HTML 字符串、Buffer、Stream、URL 数组
  • 支持流式输出:可以返回 Stream 而不只是文件
  • 支持多页面合并:可以将多个网页合并成一个 PDF(当前使用简单拼接方式,适合简单场景)
  • 支持自定义请求头(用于需要认证的页面)
  • 支持等待特定元素加载(适用于动态内容)
  • 支持错误忽略机制(可以忽略特定错误)
  • 默认文件名:如果不指定 -o 参数,会自动使用页面的 document.title 作为文件名
  • 时间戳格式:文件名中的时间戳格式为 YYYYMMDDHHmm(如:202512251539

新功能特性

✨ 流式输出

支持返回 Stream,适合管道操作和流式处理:

const result = await generatePdf('https://example.com', null);
result.stream.pipe(fs.createWriteStream('output.pdf'));

✨ 多种输入类型

  • URL'https://example.com'
  • HTML 字符串'<html>...</html>'
  • HTML BufferBuffer.from('<html>...</html>')
  • HTML Streamfs.createReadStream('input.html')
  • URL 数组['url1', 'url2'](多页面合并,当前使用简单拼接方式)

✨ 错误忽略

可以忽略特定错误,避免因非致命错误中断流程:

await generatePdf(url, './output.pdf', {
  ignore: ['timeout', /网络错误/]
});

✨ 增强配置

  • 自定义页边距:margin: { top: '20mm', right: '15mm', ... }
  • 缩放比例:scale: 0.9
  • 背景打印控制:printBackground: true/false
  • 调试模式:debug: true

注意事项

  1. 首次运行:如果使用 Puppeteer 内置的 Chromium,首次运行时会自动下载(约 200MB)
  2. 网络连接:确保可以访问目标网页
  3. 页面加载:对于动态内容较多的页面,建议增加等待时间或使用 --selector 选项
  4. 认证页面:如果需要访问需要认证的页面,使用 --header 选项或 headers 参数添加认证信息
  5. 多页面合并:当前实现使用简单的 Buffer 拼接方式,适合简单场景。如果需要专业的 PDF 合并功能(保留书签、目录、元数据等),建议使用 pdf-lib 等专业库自行实现合并逻辑
  6. 流式输出:使用流式输出时,确保及时处理 Stream,避免内存占用过大
  7. HTML 输入:使用 HTML 字符串输入时,确保 HTML 格式正确,否则可能渲染失败

故障排除

问题:找不到 Chrome

解决方案

  • macOS: 确保已安装 Google Chrome
  • Linux: 安装 Chromium 或使用 puppeteer 内置版本
  • Windows: 确保 Chrome 已安装

问题:页面加载超时

解决方案

  • 增加等待时间:-w 10000waitTime: 10000
  • 使用选择器等待:--selector "#content"selector: '#content'

问题:PDF 内容不完整

解决方案

  • 增加等待时间
  • 使用 --selectorselector 等待关键元素加载
  • 检查网页是否有动态加载的内容

问题:多页面合并失败或合并后的 PDF 无法正常打开

解决方案

  • 确保所有 URL 都可以正常访问
  • 检查网络连接
  • 使用 ignore 选项忽略非致命错误
  • 重要:当前实现使用简单的 Buffer 拼接,可能无法正确处理复杂的 PDF 结构
  • 如果需要专业的 PDF 合并功能,建议:
    1. 先分别生成各个 PDF 文件
    2. 使用 pdf-libpdf-merger-js 等专业库进行合并
    3. 或使用命令行工具如 pdftkghostscript 进行合并

专业合并示例

const { PDFDocument } = require('pdf-lib');
const { generatePdf } = require('webpage2pdf');
const fs = require('fs');

// 1. 分别生成各个 PDF
const urls = ['url1', 'url2', 'url3'];
const pdfFiles = [];
for (const url of urls) {
  const result = await generatePdf(url, `./temp-${Date.now()}.pdf`);
  if (result.success) {
    pdfFiles.push(result.path);
  }
}

// 2. 使用 pdf-lib 正确合并
const mergedPdf = await PDFDocument.create();
for (const pdfPath of pdfFiles) {
  const pdfBytes = fs.readFileSync(pdfPath);
  const pdf = await PDFDocument.load(pdfBytes);
  const pages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
  pages.forEach((page) => mergedPdf.addPage(page));
}
const mergedPdfBytes = await mergedPdf.save();
fs.writeFileSync('./merged.pdf', mergedPdfBytes);

// 3. 清理临时文件
pdfFiles.forEach(fs.unlinkSync);

问题:流式输出不工作

解决方案

  • 确保 outputPath 设置为 null
  • 检查返回的 stream 对象
  • 确保及时处理 Stream,避免内存泄漏

相关方案对比

如果你需要了解其他页面转 PDF 的方案,可以参考以下对比:

主流方案对比

| 方案 | 渲染质量 | JS支持 | 资源占用 | 速度 | 维护状态 | 成本 | |------|---------|---------|---------|------|---------|------| | Puppeteer(本项目) | ⭐⭐⭐⭐⭐ | ✅ 完整 | 高 (~200MB) | 中等 | ✅ 活跃 | 免费 | | Playwright | ⭐⭐⭐⭐⭐ | ✅ 完整 | 高 (~300MB) | 中等 | ✅ 活跃 | 免费 | | wkhtmltopdf | ⭐⭐⭐ | ⚠️ 有限 | 低 (~50MB) | 快 | ❌ 停止 | 免费 | | html2pdf.js | ⭐⭐⭐ | ⚠️ 有限 | 低 | 快 | ✅ 活跃 | 免费 | | Gotenberg | ⭐⭐⭐⭐⭐ | ✅ 完整 | 高 | 中等 | ✅ 活跃 | 免费 | | Prince XML | ⭐⭐⭐⭐⭐ | ⚠️ 有限 | 中等 | 快 | ✅ 活跃 | 💰 商业 |

方案详情

1. Puppeteer(本项目使用)

  • 技术栈:Node.js + Chrome DevTools Protocol
  • 优点:现代 Web 支持完整、动态内容处理强、渲染质量高、功能丰富
  • 缺点:资源占用大(~200MB)、启动较慢
  • 适用场景:现代 Web 应用、需要等待动态内容、需要高质量 PDF

2. Playwright

  • 技术栈:Node.js + 多浏览器引擎
  • 优点:支持多浏览器引擎、自动等待机制更智能、API 设计更现代
  • 缺点:资源占用更大、相对较新
  • 适用场景:需要跨浏览器兼容性、自动化测试 + PDF 生成

3. wkhtmltopdf

  • 技术栈:C++ + Qt WebKit
  • 优点:轻量级(~50MB)、启动速度快、资源占用小
  • 缺点:基于旧版 WebKit、不支持现代 JavaScript、CSS3 支持有限、已停止维护
  • 适用场景:简单静态页面、批量处理、资源受限环境

4. html2pdf.js / jsPDF

  • 技术栈:纯前端 JavaScript
  • 优点:无需后端支持、客户端直接生成、轻量级
  • 缺点:渲染质量一般(基于 Canvas)、不支持复杂 CSS、分页控制有限
  • 适用场景:简单页面转换、无需后端支持、客户端生成

5. Gotenberg

  • 技术栈:Docker + Chromium
  • 优点:容器化部署、基于 Chromium 渲染质量高、RESTful API
  • 缺点:需要 Docker 环境、需要服务器资源
  • 适用场景:微服务架构、容器化部署、需要 API 接口

选择建议

  • 现代 Web 应用(React/Vue/Angular):推荐 Puppeteer 或 Playwright
  • 简单静态页面:推荐 wkhtmltopdf 或 html2pdf.js
  • 批量处理:根据复杂度选择 wkhtmltopdf(简单)或 Puppeteer(复杂)
  • 微服务架构:推荐 Gotenberg
  • 前端直接生成:推荐 html2pdf.js 或 jsPDF
  • 专业排版需求:推荐 Prince XML(商业)

本项目(webpage2pdf)的优势

基于 Puppeteer,特别适合:

  • ✅ 现代 Web 应用(React/Vue/Angular)
  • ✅ 需要等待动态内容加载
  • ✅ 需要高质量 PDF 输出
  • ✅ Node.js 环境

差异化特性

  • 同时支持命令行和函数调用
  • 支持流式输出
  • 支持多种输入类型(URL、HTML、Buffer、Stream)
  • 支持多页面合并
  • 易用的 API 设计

更多详细对比请参考 README 中的"相关方案对比"章节。

语言

许可证

MIT

贡献

欢迎提交 Issue 和 Pull Request!