使用Go语言处理PDF文件的方法
发表时间: 2023-12-03 21:27
在实际开发中,会遇到将数据转换为pdf格式等情况,目前比较使用比较多的第三方库有:
gofpdf: 软件包是一个 PDF 文档生成器,支持高水平的文本、绘图和图像,不过遗憾的是不再更新了。
pdfcpu:pdfcpu是一个用Go编写的支持加密的PDF处理库。它同时提供API和CLI。
gopdf:是一个用 Go 语言编写的用于生成 PDF 文档的简单库。
ledongthuc/pdf:一个简单的读取pdf文件库
需要下载字体库simfang.ttf和示例图片
示例:
package mainimport ( "github.com/signintech/gopdf" "log")func main() { pdf := gopdf.GoPdf{} pdf.Start(gopdf.Config{ PageSize: *gopdf.PageSizeA4 , //设置密码 //Protection: gopdf.PDFProtectionConfig{ // UseProtection: true, // Permissions: gopdf.PermissionsPrint | gopdf.PermissionsCopy | gopdf.PermissionsModify, // OwnerPass: []byte("123456"), // UserPass: []byte("123456789")}, }) pdf.AddPage() // err := pdf.AddTTFFont("simfang", "./ttf/simfang.ttf") if err != nil { log.Print(err.Error()) return } err = pdf.SetFont("simfang", "", 14) if err != nil { log.Print(err.Error()) return } //透明度 //transparency := gopdf.Transparency{ // Alpha: 0.5, // BlendModeType: "", //} //pdf.SetTransparency(transparency) //页眉 pdf.AddHeader(func() { pdf.SetY(5) pdf.Cell(nil, "header") }) //页脚 pdf.AddFooter(func() { pdf.SetY(825) pdf.Cell(nil, "footer") }) //画线 pdf.SetLineWidth(2) pdf.SetLineType("dashed") pdf.Line(10, 40, 585, 40) //画椭圆 pdf.SetLineWidth(1) pdf.Oval(100, 200, 500, 500) //画多边形 pdf.SetStrokeColor(255, 0, 0) pdf.SetLineWidth(2) pdf.SetFillColor(0, 255, 0) pdf.Polygon([]gopdf.Point{{X: 10, Y: 30}, {X: 585, Y: 200}, {X: 585, Y: 250}}, "DF") //绘制带圆角的矩形 pdf.SetStrokeColor(255, 0, 0) pdf.SetLineWidth(2) pdf.SetFillColor(0, 255, 0) //pdf.SetFillColorCMYK(0, 5, 89, 0) //使用CMYK 颜色 err = pdf.Rectangle(196.6, 336.8, 398.3, 379.3, "DF", 3, 10) if err != nil { log.Print(err.Error()) return } //设置字体颜色 pdf.SetTextColor(156, 197, 140) //Set text color using RGB color model //pdf.SetTextColorCMYK(0, 6, 14, 0) //Set text color using CMYK color model //设置字体位置 x y 可以用 pdf.SetX(250) pdf.SetY(200)单独设置x或y pdf.SetXY(50, 50) //添加文字 pdf.Cell(nil, "您好") pdf.Cell(nil, "您好") //添加图片 gopdf.Rect//设置图片宽高 pdf.Image("./img/test.jpg", 50, 100, &gopdf.Rect{H: 50,W: 50}) //print image //旋转图片或文字 pdf.Rotate(270.0, 100.0, 100.0) pdf.Text("Hello...") pdf.RotateReset() //reset pdf.SetXY(50, 200) pdf.Text("Hello...") //pdf.AddPage() //增加一页 //加链接 pdf.SetXY(50, 250) pdf.Text("https://baidu.com/") pdf.AddExternalLink("https://baidu.com/", 50, 50, 125, 15)//外部链接 pdf.SetXY(50, 270) pdf.Text("Link to second page") pdf.AddInternalLink("anchor", 50, 270, 120, 15)//内部链接 pdf.AddPage() pdf.SetXY(30, 100) pdf.SetAnchor("anchor") pdf.Text("Anchor position") pdf.WritePdf("demo.pdf") pdf2 := gopdf.GoPdf{} pdf2.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) pdf2.AddPage() // 导入pdf文件 pageno是页数 tpl1 := pdf2.ImportPage("demo.pdf", 1, "/MediaBox") // Draw pdf onto page pdf2.UseImportedTemplate(tpl1, 50, 100, 400, 0) pdf2.WritePdf("demo2.pdf")}
示例2
设置页面trim-box
package mainimport ( "log" "github.com/signintech/gopdf")func main() { pdf := gopdf.GoPdf{} mm6ToPx := 22.68 // Base trim-box pdf.Start(gopdf.Config{ PageSize: *gopdf.PageSizeA4, //595.28, 841.89 = A4 TrimBox: gopdf.Box{Left: mm6ToPx, Top: mm6ToPx, Right: 595 - mm6ToPx, Bottom: 842 - mm6ToPx}, }) // Page trim-box opt := gopdf.PageOption{ PageSize: gopdf.PageSizeA4, //595.28, 841.89 = A4 TrimBox: &gopdf.Box{Left: mm6ToPx, Top: mm6ToPx, Right: 595 - mm6ToPx, Bottom: 842 - mm6ToPx}, } pdf.AddPageWithOption(opt) err := pdf.AddTTFFont("simfang", "./ttf/simfang.ttf") if err != nil { log.Print(err.Error()) return } err = pdf.SetFont("simfang", "", 14) if err != nil { log.Print(err.Error()) return } pdf.Cell(nil,"Hi") pdf.WritePdf("hello.pdf")}
示例1:
读取纯文本
package mainimport ( "bytes" "fmt" "github.com/ledongthuc/pdf")func main() { pdf.DebugOn = true content, err := readPdf("test.pdf") // Read local pdf file if err != nil { panic(err) } fmt.Println(content) return}func readPdf(path string) (string, error) { f, r, err := pdf.Open(path) // remember close file defer f.Close() if err != nil { return "", err } var buf bytes.Buffer b, err := r.GetPlainText() if err != nil { return "", err } buf.ReadFrom(b) return buf.String(), nil}
示例2
读取带样式的pdf文件
func readPdf2(path string) (string, error) { f, r, err := pdf.Open(path) // remember close file defer f.Close() if err != nil { return "", err } totalPage := r.NumPage() for pageIndex := 1; pageIndex <= totalPage; pageIndex++ { p := r.Page(pageIndex) if p.V.IsNull() { continue } var lastTextStyle pdf.Text texts := p.Content().Text for _, text := range texts { if isSameSentence(text, lastTextStyle) { lastTextStyle.S = lastTextStyle.S + text.S } else { fmt.Printf("Font: %s, Font-size: %f, x: %f, y: %f, content: %s \n", lastTextStyle.Font, lastTextStyle.FontSize, lastTextStyle.X, lastTextStyle.Y, lastTextStyle.S) lastTextStyle = text } } } return "", nil}