本文对比Node.js中三种HTML转PDF方案:html-pdf、wkhtmltopdf和phantom模块。分析显示,html-pdf不支持样式和图片;wkhtmltopdf支持URL生成但安装复杂;phantom模块通过设置viewportSize完美保留HTML排版,是保留样式和图片的最佳选择。
Node.js HTML转PDF方案概述
近期项目中遇到将HTML页面转换为PDF的需求,且要求转换后的PDF文件需完整保留原有HTML的样式与图片,包括图片、表格及CSS样式等元素。
为实现该需求,初步调研了三种技术方案,并仅对其基本用法进行了简要了解,以筛选出最适合当前场景的方案。
调研的三种方案包括:html-pdf模块、wkhtmltopdf工具以及phantom模块。最终选定phantom模块,并成功达到预期效果。下文将简要记录这三种方式的使用方法及其主要差异。
html-pdf模块使用与局限
1. html-pdf方案
GitHub仓库:https://github.com/marcbachmann/node-html-pdf NPM包地址:https://www.npmjs.com/package/html-pdf
安装步骤如下:
npm install -g html-pdf
通过命令行执行以下命令进行全局安装:
html-pdf /test/index.html index.pdf
执行上述命令后,即可将index.html页面转换为对应的index.pdf文件。
代码调用方式如下:
var express = require('express');
var router = express.Router();
var pdf = require('html-pdf');
router.get('/url',function(req,res){
res.render('html',function(err,html){
html2Pdf(html,'html.pdf');
//........
});
});
/**
* 这种方法没有渲染样式和图片
* @param url
* @param pdfName
*/
exports.html2Pdf = function(html,pdfName){
var options = {format:true};
pdf.create(html,options).toFile(__dirname+'/'+pdfName,function(err,res){
if (err) return console.log(err);
console.log(res);
});
};
测试发现,生成的PDF文件不支持样式渲染和图片加载,且无法通过URL直接加载HTML;但在分页处理方面表现良好。
转换结果如下:

wkhtmltopdf工具的优势与安装
2. wkhtmltopdf方案
GitHub仓库:https://github.com/wkhtmltopdf/wkhtmltopdf 官方文档:https://wkhtmltopdf.org
NPM包地址:https://www.npmjs.com/package/wkhtmltopdf wkhtmltopdf在效果上优于html-pdf,支持样式渲染、图片加载,并可通过URL直接生成PDF文件。但安装过程较为繁琐,具体步骤可参考官方文档。
安装完成后,可通过命令行执行以下命令:
wkhtmltopdf https://github.com github.pdf
即可生成对应的PDF文件。
代码调用方式如下:
var wkhtmltopdf = require('wkhtmltopdf');
var fs = require('fs');
// URL 使用URL生成对应的PDF
wkhtmltopdf('http://github.com', { pageSize: 'letter' })
.pipe(fs.createWriteStream('out.pdf'));
除了通过URL生成外,还支持通过HTML文件内容生成,与html-pdf类似,只要有HTML格式的字符串即可生成相应的PDF。
转换结果如下:

phantom模块的实现与选择理由
3. phantom模块方案
GitHub仓库:https://github.com/amir20/phantomjs-node 官方文档:http://amirraminfar.com/phantomjs-node/ NPM包地址:https://www.npmjs.com/package/phantom phantomjs是基于Webkit的无头浏览器,提供JavaScript API。Node.js通过模块化封装使其能在Node.js环境中使用。
模块安装方式如下:
Node.js 6.X及以上版本:
npm install phantom –save
Node.js 5.X版本:
npm install phantom@3 –save
Node.js 4.X及以下版本:
npm install phantom@2 –save
以下示例均基于Node.js 4.x版本。
代码调用方式如下:
var phantom = require('phantom');
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.open("https://www.oracle.com/index.html").then(function(status) {
page.property('viewportSize',{width: 10000, height: 500});
page.render('/oracle10000.pdf').then(function(){
console.log('Page rendered');
ph.exit();
});
});
});
});
代码中,phantom可通过URL转换为PDF,并通过page.property('viewportSize',{width:width,height:height})设置生成的PDF宽度和高度。
此例中phantom未实现分页,而是以整个浏览器截图形式获取全文,并转化为PDF格式。
选择phantom的主要原因在于其便于设置PDF宽度,能更好地兼容HTML排版。
转换结果如下:
