(1)JSPDF(前端生成 )
(2)PDFKit( 服务端生成)
(3)node-html-pdf(服务端生成)
(4)JSPDF + HTMLToCanvas(前端生成)
(5) 使用打印(前端生成)
PDFKit使用来在Node服务端生成PDF文件的JS包(也支持在浏览器使用),它可以轻松生成复杂的、多页的、可打印的PDF文档。
它的API是链式语法,与操作Canvas的API有一些类似
安装:
npm install pdfkit -S
创建PDFKit文档很容易:
const PDFDocument = require('pdfkit');
const doc = new PDFDocument();
PDFDocument实例是可读的Node流,它不会自动的保存,但是可以使用pipe
方法将输出的PDF文档传递给另一个可写的Node流。当PDF文档编写成功后,调用end
方法来结束流程。下面的例子来展示如何将生成的文档传递给PDF文件或者HTTP响应:
doc.pipe(fs.createWriteStream('/path/to/file.pdf')); // 写入PDF文件
doc.pipe(res); // 传递给HTTP响应
// 用后面介绍的API来为PDF添加内容
// 结束编辑,关闭流
doc.end();
PDFKit的0.6版本后支持在浏览器中使用,有两种方法在浏览器端使用PDFKit,一种是在浏览器端使用browserify加载Node模块,另一种方法是直接使用PDFKit的预编译版本,可以从Github上下载。
在浏览器端使用PDFKit和Node中使用的唯一区别就是输出结果,在浏览器端输出结果必须是浏览器支持的格式,比如Blob。Blob格式可以允许浏览器在一个iframe中直接展示生成的PDF文档,或者将PDF上传到服务器,或者让用户下载它。
将PDFDcument输出为Blob格式,需要将他传递给blob-stream,这个模块可以将Node的流转换为Blob。下面的例子使用了Browserify来加载PDFKit和blob-stram(如果没有使用Browserify可以直接使用标签代替)
// 引入依赖
const PDFDocument = require('pdfkit');
const blobStream = require('blob-stream');
// 创建文档
const doc = new PDFDocument();
// 传递给Blob
const stream = doc.pipe(blobStream());
// 在这里添加PDF的内容
// 结束时得到的是Blob
doc.end();
stream.on('finish', function() {
// 将blob转换为PDF文档
const blob = stream.toBlob('application/pdf');
// 或者得到Blob URL,直接在浏览器中展示
const url = stream.toBlobURL('application/pdf');
iframe.src = url;
});
PDFKit文档的第一页是在创建文档时自动添加的,除非使用了autoFirstPage: false
选项。后续的页面必须手动添加:
doc.addPage()
可以使用pageAdded
事件,让每个页面创建后都添加上相同的内容:
doc.on('pageAdded', () => doc.text("Page Title"));
可以通过为addPage
传递参数设置页面的尺寸、方向:
layout
,页面方向,可取值portrait
(默认值)/landscape
size
,页面尺寸,取值是一个数组[宽, 高]
,单位是PDF的点(1/72英寸)。可以传入字符串指定一些预设值,默认值是letter
margin
,设定页边距,可以设为一个数字,那么各边距都等于它,也可以设为一个对象,分top
/left
/bottom
/right
四个属性分别设定各边距// Add a 50 point margin on all sides
doc.addPage({
margin: 50});
// Add different margins on each side
doc.addPage({
margins: {
top: 50,
bottom: 50,
left: 72,
right: 72
}
});
给PDFDocument构造函数传递页面参数对象,可以设置每一页的默认尺寸和布局,它会被每个addPage
传递的页面参数覆盖。
bufferPage
有的时候需要在后面的页面完成后回到前面的页面,对前面的页面进行修改,可以在PDFDocument构造函数传递一个参数bufferPages: true
,来手动控制页面流。
一般这个情况可能不多见,具体可以参考文档这部分内容。
基础信息包括标题、作者等,可以通过对doc.info
赋值,也可以在创建文档时传递参数实现。可以设定的基础信息包括(需要首字母大写)Title
/Author
/Subject
/Keywords
/CreationDate
/ModDate
可以对PDF加密,并且使用密码打开文件。也可以设定PDF文件的访问权限。具体内容参考文档。
PDF格式兼容矢量图形,PDFKit提供了类似于HTML5 Canvas的API来创建矢量图形。图形通过一些列的直线和曲线构成,看一个例子:
doc.moveTo(0, 20) // 设定起点
.lineTo(100, 160) // 直线
.quadraticCurveTo(130, 200, 150,