使用Go语言处理PDF文件的方法

发表时间: 2023-12-03 21:27

在实际开发中,会遇到将数据转换为pdf格式等情况,目前比较使用比较多的第三方库有:

  • https://github.com/jung-kurt/gofpdf
  • https://github.com/signintech/gopdf
  • https://github.com/pdfcpu/pdfcpu
  • https://github.com/ledongthuc/pdf

gofpdf: 软件包是一个 PDF 文档生成器,支持高水平的文本、绘图和图像,不过遗憾的是不再更新了。

pdfcpu:pdfcpu是一个用Go编写的支持加密的PDF处理库。它同时提供API和CLI。

gopdf:是一个用 Go 语言编写的用于生成 PDF 文档的简单库。
ledongthuc/pdf:一个简单的读取pdf文件库

用gopdf创建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")}

用ledongthuc/pdf读取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}