go语言生成PDF
最近由于工作需要,将之前用phantomjs生成PDF报告的部分重构(phantomjs在数据量较大时候,占用太高的服务器资源),改用go代码直接生成,在GitHub上搜索相关第三方库, 关键词:pdf language:Go,按照star排序如图:
在各大网站上查找相关资料后,大致了解如下:
- jung-kurt/gofpdf 的star数量较多,但是更新频率较低,在我用的时候,最新的tag是v2.17.2,已经有将近两年没更新了,有很多open的issue没有关,担心不会再更新,所以当时没有考虑用这个。
另外,go语言中文网有一篇文章说这个包不支持中文,是的,那篇文章是2017年的,当时不支持,这个库2019年更新了,现在是支持的。
- 排在第二的是gotenberg/gotenberg,这个库主要用于将其他类型的文件转化为PDF,以及合并PDF的,不符合我们的需求,暂不考虑。
- pdfcpu/pdfcpu 是一个用于合并PDF的命令行工具,也不符合需求,暂不考虑。
- signintech/gopdf 初步看着还是比较符合需求,再看一看其他的。
- unidoc/unipdf 是unioffice的一个PDF工具,他们还有个比较厉害的用于生成word的库,不过使用需要商业授权,源码也做了混淆,加上文档有限,不是太好用,先不考虑了。
附unipdf部分源码截图:
最终,对比了多个第三方库之后,选用了signintech/gopdf。
这个库的部分功能还有待完善,比如自动分页,自动换行等。大纲书签功能,之前只有最基本的跳转功能,而且跳转功能有些问题,会跳转到下一页,我提交了一次优化,并附带了demo,现在作者已经将我提交的那部分合入了。
代码示例:
package main
import (
"log"
"github.com/signintech/gopdf"
)
func main() {
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{ PageSize: *gopdf.PageSizeA4 })
pdf.AddPage()
err := pdf.AddTTFFont("wts11", "../ttf/wts11.ttf")
if err != nil {
log.Print(err.Error())
return
}
err = pdf.SetFont("wts11", "", 14)
if err != nil {
log.Print(err.Error())
return
}
pdf.Cell(nil, "您好")
pdf.WritePdf("hello.pdf")
}
先来说说这个库使用的大致流程(如上面代码块):
- 首先下载并在代码里引入这个包:
import "github.com/signintech/gopdf"
; - 初始化一个pdf对象:
pdf := gopdf.GoPdf{}
; - 初始化配置(页面尺寸):
pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})
;这里的PageSizeA4
指的是用A4纸的尺寸,即宽210mm,高297mm;在分辨率为72px/inch的时候,宽高分为约为595px、842px,使用px更符合实际场景,比如UI给的设计稿一般都是像素单位; - 添加一页画布:
pdf.AddPage()
- 添加字体,可以从ttf文件直接读取,也可以使用字节流的字体数据:
err := pdf.AddTTFFont("wts11", "../ttf/wts11.ttf")
,可以在初始化的时候添加多个字体,以便后续在不同地方选用不同的字体; - 设置字体:
pdf.SetFont("wts11", "", 14)
,这里的wts11是上面设置的,如果上面设置的是abc,这里用的时候也是abc。这一步一定不要忘记,否则生成的时候回抛一个空指针异常; - 绘制内容,可以是文字、线条、图片、图形、填充颜色等等,自由度极高。(但是文字不会自动换行…)
- 保存输出到pdf文件:
pdf.WritePdf("hello.pdf")
;
相关代码示例和使用注意事项后续有空了再详细写写。
gopdf使用注意事项及常见问题