快照功能,把html页面直接生成图片或pdf

函数计算动态扩展

Google开源工具实战:Puppeteer 一键将HTML页面生成图片/PDF

Google官方开源的、能直接把HTML页面(本地/远程)转换成图片或PDF的工具,首推 Puppeteer(Chrome团队开源的Node.js库,基于Chrome DevTools协议)——它本质是“无头Chrome”,能模拟浏览器渲染页面,完美实现HTML→图片/PDF的转换,功能强大且完全免费,下面我会把安装、核心用法、自定义配置全讲清楚,新手也能直接跑通。

一、先了解:Puppeteer 是什么?

Puppeteer 是Google Chrome团队推出的Node.js开源库,核心能力是通过代码控制无头Chrome/Chromium浏览器

  • 支持渲染完整HTML(包括CSS、JS、图片、字体);
  • 一键生成高清图片(PNG/JPG/WebP)或标准化PDF;
  • 兼容本地HTML文件、远程URL、动态渲染的页面(如Vue/React前端页面);
  • 可自定义尺寸、分辨率、PDF页码/页眉页脚、图片质量等。

简单说:它就像“无界面的Chrome”,先让浏览器完整渲染页面,再把渲染结果导出为图片/PDF,保证和浏览器显示效果100%一致。

二、环境准备(两步搞定)

1. 安装Node.js

Puppeteer基于Node.js运行,先安装Node.js(推荐14.x及以上版本):

2. 安装Puppeteer

在项目目录下执行命令(会自动下载轻量版Chromium,无需手动装Chrome):

1
2
3
4
5
# 核心安装(推荐,包含Chromium)
npm install puppeteer

# 可选:仅装核心库,使用本地已安装的Chrome(节省空间)
npm install puppeteer-core

⚠️ 注意:国内安装可能因网络问题卡住,可配置淘宝镜像:

1
2
npm config set puppeteer_download_host=https://npm.taobao.org/mirrors
npm install puppeteer

三、核心实战:HTML转图片/PDF(完整代码)

场景1:远程URL 转图片/PDF

比如把百度首页转换成图片和PDF,代码可直接复制运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
const puppeteer = require('puppeteer');

// 封装转换函数
async function htmlToImageAndPdf() {
// 1. 启动无头浏览器(headless: true 表示无界面,false 可看到浏览器窗口)
const browser = await puppeteer.launch({
headless: true,
// 解决部分系统字体缺失、渲染乱码问题(Windows/Linux需配置)
args: ['--no-sandbox', '--disable-setuid-sandbox']
});

// 2. 打开新页面
const page = await browser.newPage();

// 3. 设置页面尺寸(可选,默认800x600)
await page.setViewport({
width: 1920, // 宽度
height: 1080, // 高度
deviceScaleFactor: 2 // 分辨率(2=2K,1=1080P,越高图片越清晰)
});

// 4. 访问远程URL(等待页面完全加载)
await page.goto('https://www.baidu.com', {
waitUntil: 'networkidle0' // 等待网络请求全部完成(适合动态页面)
});

// ========== 生成图片 ==========
await page.screenshot({
path: 'baidu.png', // 保存路径(支持png/jpg/webp)
fullPage: true, // 是否截取整页(false仅截取当前视口)
quality: 100 // 图片质量(仅jpg/webp有效,0-100)
});
console.log('图片生成完成:baidu.png');

// ========== 生成PDF ==========
await page.pdf({
path: 'baidu.pdf', // 保存路径
format: 'A4', // 纸张尺寸(A4/A3/Letter等)
printBackground: true, // 是否打印背景(含CSS背景色/图片)
margin: { // 页面边距
top: '20px',
right: '20px',
bottom: '20px',
left: '20px'
}
});
console.log('PDF生成完成:baidu.pdf');

// 5. 关闭浏览器
await browser.close();
}

// 执行函数
htmlToImageAndPdf();

场景2:本地HTML文件 转图片/PDF

如果要转换本地的HTML文件(比如index.html),只需修改page.gotopage.goto('file://' + __dirname + '/index.html')

1
2
3
4
// 替换场景1中的step4:访问本地HTML文件
await page.goto(`file://${__dirname}/index.html`, {
waitUntil: 'domcontentloaded' // 等待DOM加载完成
});

⚠️ 注意:本地HTML引用的CSS/JS/图片需用相对路径,或绝对路径(如file:///Users/xxx/project/style.css)。

场景3:直接传入HTML字符串 转图片/PDF

无需本地文件/远程URL,直接传入HTML字符串渲染:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 替换场景1中的step4:直接渲染HTML字符串
const htmlContent = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试页面</title>
<style>body { font-size: 20px; color: red; }</style>
</head>
<body>
<h1>Hello Puppeteer!</h1>
<p>这是直接渲染的HTML字符串</p>
</body>
</html>
`;
await page.setContent(htmlContent, {
waitUntil: 'domcontentloaded'
});

四、关键配置详解(自定义需求)

1. 图片生成(screenshot)核心参数

参数 作用 示例
path 保存路径(省略则返回二进制数据) path: 'output.png'
fullPage 是否截取整页(滚动到底部) fullPage: true
quality 图片质量(0-100,仅jpg/webp) quality: 90
type 图片格式(png/jpg/webp) type: 'jpg'
clip 截取指定区域(x/y/width/height) clip: {x: 0, y: 0, width: 500, height: 500}
omitBackground 透明背景(仅png/webp) omitBackground: true

2. PDF生成(pdf)核心参数

参数 作用 示例
path 保存路径(省略则返回二进制数据) path: 'output.pdf'
format 纸张尺寸 format: 'A4'/'Letter'/'Legal'
printBackground 打印背景色/图片(关键!默认false) printBackground: true
margin 页面边距 margin: {top: '1cm', right: '1cm'}
displayHeaderFooter 显示页眉页脚 displayHeaderFooter: true
headerTemplate 自定义页眉(HTML) headerTemplate: '<div style="font-size:10px">页眉</div>'
footerTemplate 自定义页脚(支持页码) footerTemplate: '<div>第<span class="pageNumber"></span>页,共<span class="totalPages"></span>页</div>'
pageRanges 指定页码范围 pageRanges: '1-3'(仅生成1-3页)

五、进阶用法与避坑指南

1. 处理动态页面(Vue/React/异步数据)

如果页面有异步请求、懒加载内容,需等待页面完全渲染:

1
2
3
4
5
6
7
8
// 方式1:等待网络空闲(推荐)
await page.goto(url, { waitUntil: 'networkidle0' });

// 方式2:手动等待指定时间(适合懒加载)
await page.waitForTimeout(2000); // 等待2秒

// 方式3:等待指定元素出现
await page.waitForSelector('#data-list', { timeout: 5000 }); // 等待#data-list元素加载

2. 解决中文乱码/字体缺失

Linux服务器/无桌面环境下,可能因缺少中文字体导致渲染乱码,需安装中文字体:

1
2
3
4
5
# Ubuntu/Debian
sudo apt install fonts-wqy-microhei fonts-wqy-zenhei

# CentOS/RHEL
sudo yum install wqy-microhei-fonts wqy-zenhei-fonts

3. 批量转换多个HTML/URL

1
2
3
4
5
6
7
8
9
10
11
12
13
// 批量转换URL列表
const urls = ['https://www.baidu.com', 'https://www.google.com'];
async function batchConvert() {
const browser = await puppeteer.launch();
for (let i = 0; i < urls.length; i++) {
const page = await browser.newPage();
await page.goto(urls[i], { waitUntil: 'networkidle0' });
// 生成图片
await page.screenshot({ path: `output-${i}.png`, fullPage: true });
await page.close(); // 关闭当前页面,避免内存泄漏
}
await browser.close();
}

4. 性能优化

  • 复用浏览器实例:批量转换时,不要每次都launch/close浏览器,复用实例可提升速度;
  • 降低分辨率:deviceScaleFactor设为1(而非2),减少图片体积;
  • 禁用不必要的功能:如--disable-images(仅转PDF且不需要图片时)。

六、总结

关键点回顾

  1. 核心工具:Google开源的Puppeteer是HTML转图片/PDF的最佳选择,基于无头Chrome,渲染效果和浏览器一致;
  2. 核心步骤:安装Node.js → 安装Puppeteer → 启动浏览器 → 渲染HTML(本地/远程/字符串) → 导出图片/PDF;
  3. 关键配置:
    • 图片:fullPage: true(整页)、quality(质量)、deviceScaleFactor(分辨率);
    • PDF:printBackground: true(打印背景)、format(纸张尺寸)、margin(边距);
  4. 避坑点:解决中文乱码需安装中文字体,动态页面需等待加载完成,批量转换复用浏览器实例。

Puppeteer几乎能满足所有HTML转图片/PDF的需求,不管是简单的静态页面,还是复杂的动态前端页面,都能完美渲染。如果需要打包成可执行文件(无需Node.js环境),或集成到Web服务中,可留言我补充相关方案。


快照功能,把html页面直接生成图片或pdf
https://cszy.top/2018-06-22 快照功能,把html页面直接生成图片/
作者
csorz
发布于
2018年6月22日
许可协议