html-pdf 中文教程
1. 项目概述
html-pdf 是一个基于 Node.js 的 HTML 到 PDF 转换工具,它使用 PhantomJS 来渲染 HTML 内容并生成 PDF 文档。它提供了简单易用的 API,允许开发者将静态 HTML 或动态生成的 HTML 转换为高质量的 PDF 文档。
- 官方 GitHub 仓库:https://github.com/marcbachmann/node-html-pdf
- 适用环境:Node.js
- 主要特点:将 HTML 内容转换为 PDF 文档、支持 CSS 样式、页眉页脚设置等
2. 核心功能
2.1 基本功能
- HTML 转换:将 HTML 文件或字符串转换为 PDF 文档
- CSS 支持:支持内联 CSS、外部 CSS 文件和 CSS 框架
- 页面设置:设置页面大小、边距、方向等
- 页眉页脚:添加和设置页眉页脚
- 页面编号:在页眉页脚中添加页码
- 输出选项:保存为文件或返回缓冲区
2.2 高级功能
- 自定义字体:添加和使用自定义字体
- 图片支持:处理 HTML 中的图片
- JavaScript 支持:执行 HTML 中的 JavaScript 代码
- 延迟渲染:等待指定时间或事件后再渲染
- 水印功能:添加水印到 PDF 文档
- 加密选项:设置 PDF 文档的密码和权限
3. 安装与设置
3.1 在 Node.js 环境中安装
npm install html-pdf3.2 基本配置
html-pdf 不需要额外的配置,但需要注意它依赖于 PhantomJS,安装过程中会自动下载。
4. 基本使用示例
4.1 转换 HTML 文件
// 导入库
const pdf = require('html-pdf');
const fs = require('fs');
// 读取 HTML 文件
const html = fs.readFileSync('path/to/file.html', 'utf8');
// 设置转换选项
const options = {
format: 'A4',
orientation: 'portrait',
border: '10mm',
timeout: 30000 // 30秒超时
};
// 转换并保存为 PDF 文件
pdf.create(html, options).toFile('output.pdf', (err, res) => {
if (err) return console.error(err);
console.log('PDF 文档创建成功:', res.filename);
});4.2 转换 HTML 字符串
// 导入库
const pdf = require('html-pdf');
// HTML 字符串
const html = `
<!DOCTYPE html>
<html>
<head>
<title>测试文档</title>
<style>
body { font-family: Arial, sans-serif; }
h1 { color: #333; }
.container { padding: 20px; }
</style>
</head>
<body>
<div class="container">
<h1>Hello World!</h1>
<p>这是使用 html-pdf 库创建的 PDF 文档。</p>
</div>
</body>
</html>
`;
// 设置转换选项
const options = {
format: 'Letter',
border: {
top: '1in',
right: '1in',
bottom: '1in',
left: '1in'
}
};
// 转换并保存为 PDF 文件
pdf.create(html, options).toFile('test.pdf', (err, res) => {
if (err) return console.error(err);
console.log('PDF 文档创建成功:', res.filename);
});4.3 获取 PDF 缓冲区
// 导入库
const pdf = require('html-pdf');
// HTML 字符串
const html = '<h1>Hello World!</h1><p>这是一个测试文档。</p>';
// 设置转换选项
const options = {
format: 'A4'
};
// 转换为缓冲区
pdf.create(html, options).toBuffer((err, buffer) => {
if (err) return console.error(err);
console.log('PDF 缓冲区创建成功,大小:', buffer.length, '字节');
// 可以将缓冲区发送给客户端或进行其他处理
});4.4 使用 Promise 接口
// 导入库
const pdf = require('html-pdf');
// HTML 字符串
const html = '<h1>Hello World!</h1><p>这是一个测试文档。</p>';
// 设置转换选项
const options = {
format: 'A4'
};
// 使用 Promise 接口
pdf.create(html, options).toFile('output.pdf')
.then(res => {
console.log('PDF 文档创建成功:', res.filename);
})
.catch(err => {
console.error('创建 PDF 文档时出错:', err);
});5. 高级用法
5.1 设置页眉页脚
// 导入库
const pdf = require('html-pdf');
// HTML 字符串
const html = `
<!DOCTYPE html>
<html>
<head>
<title>测试文档</title>
<style>
body { font-family: Arial, sans-serif; }
h1 { color: #333; }
.container { padding: 20px; }
</style>
</head>
<body>
<div class="container">
<h1>Hello World!</h1>
<p>这是使用 html-pdf 库创建的 PDF 文档。</p>
<p>页面 1 内容</p>
<div style="page-break-after: always;"></div>
<p>页面 2 内容</p>
</div>
</body>
</html>
`;
// 设置转换选项
const options = {
format: 'A4',
border: {
top: '40px',
right: '20px',
bottom: '40px',
left: '20px'
},
header: {
height: '30px',
contents: '<div style="text-align: center; font-size: 10px;">文档页眉</div>'
},
footer: {
height: '30px',
contents: {
default: '<div style="text-align: center; font-size: 10px;">页码: {{page}} / {{pages}}</div>'
}
}
};
// 转换并保存为 PDF 文件
pdf.create(html, options).toFile('header-footer-example.pdf', (err, res) => {
if (err) return console.error(err);
console.log('带页眉页脚的 PDF 文档创建成功:', res.filename);
});5.2 使用自定义字体
// 导入库
const pdf = require('html-pdf');
// HTML 字符串
const html = `
<!DOCTYPE html>
<html>
<head>
<title>测试文档</title>
<style>
@font-face {
font-family: 'CustomFont';
src: url('path/to/font.ttf');
}
body { font-family: 'CustomFont', Arial, sans-serif; }
h1 { color: #333; }
</style>
</head>
<body>
<h1>Hello World!</h1>
<p>这是使用自定义字体的 PDF 文档。</p>
</body>
</html>
`;
// 设置转换选项
const options = {
format: 'A4'
};
// 转换并保存为 PDF 文件
pdf.create(html, options).toFile('custom-font-example.pdf', (err, res) => {
if (err) return console.error(err);
console.log('带自定义字体的 PDF 文档创建成功:', res.filename);
});5.3 处理图片
// 导入库
const pdf = require('html-pdf');
// HTML 字符串
const html = `
<!DOCTYPE html>
<html>
<head>
<title>测试文档</title>
<style>
body { font-family: Arial, sans-serif; }
h1 { color: #333; }
.container { padding: 20px; }
img { max-width: 100%; height: auto; }
</style>
</head>
<body>
<div class="container">
<h1>图片示例</h1>
<p>这是一张图片:</p>
<img src="path/to/image.jpg" alt="测试图片">
<p>图片下方的文字</p>
</div>
</body>
</html>
`;
// 设置转换选项
const options = {
format: 'A4'
};
// 转换并保存为 PDF 文件
pdf.create(html, options).toFile('image-example.pdf', (err, res) => {
if (err) return console.error(err);
console.log('带图片的 PDF 文档创建成功:', res.filename);
});5.4 使用 JavaScript
// 导入库
const pdf = require('html-pdf');
// HTML 字符串
const html = `
<!DOCTYPE html>
<html>
<head>
<title>测试文档</title>
<style>
body { font-family: Arial, sans-serif; }
h1 { color: #333; }
.container { padding: 20px; }
.dynamic-content { margin-top: 20px; padding: 10px; background: #f0f0f0; }
</style>
</head>
<body>
<div class="container">
<h1>JavaScript 示例</h1>
<p>这是一个使用 JavaScript 的 PDF 文档。</p>
<div class="dynamic-content" id="dynamicContent"></div>
</div>
<script>
// 动态生成内容
document.getElementById('dynamicContent').innerHTML = '<p>这是由 JavaScript 动态生成的内容</p><p>当前时间: ' + new Date().toLocaleString() + '</p>';
</script>
</body>
</html>
`;
// 设置转换选项
const options = {
format: 'A4',
renderDelay: 1000 // 延迟 1 秒以确保 JavaScript 执行完成
};
// 转换并保存为 PDF 文件
pdf.create(html, options).toFile('javascript-example.pdf', (err, res) => {
if (err) return console.error(err);
console.log('带 JavaScript 的 PDF 文档创建成功:', res.filename);
});6. 实际应用场景
6.1 生成报告
使用 html-pdf 库从数据库或 API 获取数据,生成包含表格、图表和格式化文本的专业报告。
6.2 自动化文档生成
根据用户输入或模板自动生成个性化文档,如合同、发票、简历等。
6.3 教育内容创建
为在线课程生成包含教程内容、练习和答案的 PDF 文档。
6.4 商业文档管理
创建和管理企业内部文档,如员工手册、政策文档、培训材料等。
6.5 票据生成
生成各种票据,如发票、收据、门票等,包含条形码或二维码。
7. 代码优化建议
7.1 模块化设计
将 PDF 生成逻辑拆分为多个模块,提高代码可维护性:
// PDF 生成器模块
class PdfGenerator {
constructor() {
this.pdf = require('html-pdf');
}
createPdf(html, options) {
return new Promise((resolve, reject) => {
this.pdf.create(html, options).toFile((err, res) => {
if (err) reject(err);
else resolve(res);
});
});
}
createReport(data, template) {
// 渲染模板
const html = this.renderTemplate(template, data);
// 设置选项
const options = {
format: 'A4',
border: '10mm'
};
return this.createPdf(html, options);
}
renderTemplate(template, data) {
// 简单的模板渲染逻辑
let html = template;
for (const key in data) {
html = html.replace(new RegExp(`{{${key}}}`, 'g'), data[key]);
}
return html;
}
}
// 使用示例
const generator = new PdfGenerator();
const data = {
title: '销售报告',
date: new Date().toLocaleDateString(),
sales: '10000'
};
const template = '<h1>{{title}}</h1><p>日期: {{date}}</p><p>销售额: {{sales}}</p>';
generator.createReport(data, template)
.then(res => {
console.log('报告生成成功:', res.filename);
})
.catch(err => {
console.error('生成报告时出错:', err);
});7.2 错误处理
添加适当的错误处理,提高代码健壮性:
try {
const pdf = require('html-pdf');
const html = '<h1>Hello World!</h1>';
const options = { format: 'A4' };
pdf.create(html, options).toFile('document.pdf', (err, res) => {
if (err) {
console.error('创建 PDF 文档时出错:', err);
// 处理错误
return;
}
console.log('PDF 文档创建成功:', res.filename);
});
} catch (error) {
console.error('初始化 PDF 生成器时出错:', error);
// 处理错误
}7.3 性能优化
对于大型 PDF 文档,使用异步操作和适当的超时设置:
async function generateLargePdf(html, filename) {
try {
const pdf = require('html-pdf');
const options = {
format: 'A4',
timeout: 60000, // 增加超时时间
renderDelay: 2000 // 增加渲染延迟
};
return new Promise((resolve, reject) => {
pdf.create(html, options).toFile(filename, (err, res) => {
if (err) reject(err);
else resolve(res);
});
});
} catch (error) {
console.error('生成大型 PDF 文档时出错:', error);
throw error;
}
}
// 使用示例
generateLargePdf(largeHtml, 'large-document.pdf')
.then(res => {
console.log('大型 PDF 文档生成成功:', res.filename);
})
.catch(err => {
console.error('生成大型 PDF 文档时出错:', err);
});7.4 内存管理
对于大型 HTML 内容,注意内存使用:
// 避免一次性加载大型 HTML 文件到内存
function generatePdfFromStream(stream, filename) {
const pdf = require('html-pdf');
let html = '';
stream.on('data', chunk => {
html += chunk;
});
stream.on('end', () => {
const options = {
format: 'A4'
};
pdf.create(html, options).toFile(filename, (err, res) => {
if (err) return console.error(err);
console.log('PDF 文档创建成功:', res.filename);
// 释放内存
html = null;
});
});
stream.on('error', error => {
console.error('读取流时出错:', error);
});
}8. 总结
html-pdf 是一个功能强大、灵活易用的 Node.js 库,为开发者提供了将 HTML 转换为 PDF 文档的能力。它的主要优势包括:
- 易于使用:简单的 API 设计,易于与现有项目集成
- 功能丰富:支持从基本 HTML 转换到复杂的页眉页脚、自定义字体等
- 高度可定制:支持多种配置选项和高级功能
- 稳定可靠:基于 PhantomJS 的成熟技术
通过本教程的学习,您应该已经掌握了 html-pdf 的基本用法和一些高级技巧,可以开始在实际项目中应用它来生成 PDF 文档了。