零散专题32 生成PDF

生成pdf的方案

(1)JSPDF(前端生成 )

  • 优点:不需要服务端安装无头浏览器,使用CSS方便控制样式,生成的PDF文字可复制
  • 缺点:对中文支持不好

(2)PDFKit( 服务端生成)

  • 优点:服务端直接解决,生成的PDF文字可复制,通过引入字体,可支持中文
  • 缺点:样式控制复杂

(3)node-html-pdf(服务端生成)

  • 优点:服务端通过控制HTML模板生成PDF,支持中文,样式控制方便
  • 缺点:不支持图片,需要安装无头浏览器,性能有隐患

(4)JSPDF + HTMLToCanvas(前端生成)

  • 优点:样式控制方便,支持中文,比较美观
  • 缺点:生成的PDF内容是图片,无法复制

(5) 使用打印(前端生成)

  • 优点:简单,代码量少
  • 缺点:需要引导用户,且不美观

PDFKit

简介

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可以直接使用<script>标签代替)

// 引入依赖
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)                            // 直线
  .q
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值