PDF简介
PDF(Portable Document Format)是Adobe公司发明的一种文档格式,由于其具有很多独特的优点而被广泛使用。如pdf可内嵌字体,这样就可以避免客户端没有安装字体而显示不一致;如pdf的图片和文字使用了矢量图,这样就可以随意放大而不会失真;另外pdf的加密和防篡改也是一大亮点,是向外发布资料的首选格式
PDF文件结构
一个未经修改的PDF文件从头到尾主要包括4个部分,分别是:文件头、对象集合、交叉引用表、文件尾。其中:
- 文件头是固定的一行
%PDF-1.4
- 对象集合是文档的主要组成部分,每个对象由obj/endobj行包裹
1 0 obj
<</Producer (Skia/PDF m92)>>
endobj
- 交叉引用表以xref为开始标志,用于表示对象集合中每个对象的偏移地址
xref
0 83
0000000000 65535 f
0000000015 00000 n
0000010954 00000 n
- 文件尾以trailer为开始标志,一直到文件结束。其中包含了对象个数、root对象号、交叉引用表的开始位置等文档结构信息,以及文件的元信息、加密信息等内容,最后以%%EOF结尾
trailer
<</Size 83
/Root 11 0 R
/Info 1 0 R>>
startxref
50152
%%EOF
iOS生成PDF
iOS可以通过UIGraphicsPDFRenderer类生成PDF,其本身的api非常简单:一个init方法,一个写入文件的方法,一个导出data数据的方法
init(bounds: CGRect, format: UIGraphicsPDFRendererFormat)
用于构造UIGraphicsPDFRenderer,第一个参数是pdf的尺寸,第二个参数可以设置pdf文件的元数据
func writePDF(to url: URL, withActions actions: (UIGraphicsPDFRendererContext) -> Void) throws
生成pdf并写入到指定URL
func pdfData(actions: (UIGraphicsPDFRendererContext) -> Void) -> Data
生成pdf并返回Data
绘制PDF主要依靠UIGraphicsPDFRendererContext
,这是UIGraphicsRendererContext的子类,所以iOS是使用CoreGraphics的draw api进行pdf绘制的
- 设置填充颜色:
func setFillColor(_ color: CGColor)
: - 绘制矩形:
func fill(_ rect: CGRect)
- 绘制文字:创建NSAttributedString,通过
draw(in rect: CGRect)
绘制到context上 - 绘制图片:创建UIImage,通过
draw(in rect: CGRect)
绘制到context上
除了CoreGraphics的相关api之外,最重要的是func beginPage()
,用于创建一页pdf
如何用安卓生成pdf文件
安卓可以使用PdfDocument类生成PDF,和iOS类似,采用了系统的绘图api(Canvas
),对于开发者来说学习成本很低。但是安卓的坑比较多,建议采用iText、PDFBox等第三方实现。如drawText不支持多行文本,要通过较复杂的操作来实现;某些系统对文档内的图片不进行压缩,导致生成的pdf比正常的大10多倍
如何用flutter生成pdf文件
flutter可以使用pdf库生成pdf,该库实现了一套自己的widgets,开发者可以像写普通widgets一样去写pdf;另外还提供了table相关的api,不用手动画表格,还支持自动分页,非常友好。