[ go使用pdf ]


gopdf gopdf is a simple library for generating PDF document written in Go lang.

A minimum version of Go 1.13 is required.

Features Unicode subfont embedding. (Chinese, Japanese, Korean, etc.) Draw line, oval, rect, curve Draw image ( jpg, png ) Set image mask Password protection Font kerning Installation go get -u github.com/signintech/gopdf Print text

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")

}

Set text color using RGB color model pdf.SetTextColor(156, 197, 140) pdf.Cell(nil, "您好") Set text color using CMYK color model pdf.SetTextColorCMYK(0, 6, 14, 0) pdf.Cell

Image

package main
import (
    "log"
    "github.com/signintech/gopdf"
)

func main() {
    pdf := gopdf.GoPdf{}
    pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4 })  
    pdf.AddPage()
    var err error
    err = pdf.AddTTFFont("loma", "../ttf/Loma.ttf")
    if err != nil {
        log.Print(err.Error())
        return
    }

    pdf.Image("../imgs/gopher.jpg", 200, 50, nil) //print image
    err = pdf.SetFont("loma", "", 14)
    if err != nil {
        log.Print(err.Error())
        return
    }
    pdf.SetXY(250, 200) //move current location
    pdf.Cell(nil, "gopher and gopher") //print text

    pdf.WritePdf("image.pdf")
}
package main

import (
    "log"
    "github.com/signintech/gopdf"
)

func main()  {
    pdf := gopdf.GoPdf{}
    pdf.Start(gopdf.Config{ PageSize: *gopdf.PageSizeA4 }) //595.28, 841.89 = A4
    pdf.AddPage()
    err := pdf.AddTTFFont("times", "./test/res/times.ttf")
    if err != nil {
        log.Print(err.Error())
        return
    }

    err = pdf.SetFont("times", "", 14)
    if err != nil {
        log.Print(err.Error())
        return
    }

    pdf.SetXY(30, 40)
    pdf.Text("Link to example.com")
    pdf.AddExternalLink("http://example.com/", 27.5, 28, 125, 15)

    pdf.SetXY(30, 70)
    pdf.Text("Link to second page")
    pdf.AddInternalLink("anchor", 27.5, 58, 120, 15)

    pdf.AddPage()
    pdf.SetXY(30, 100)
    pdf.SetAnchor("anchor")
    pdf.Text("Anchor position")

    pdf.WritePdf("hello.tmp.pdf")

}
package main

import (
    "log"
    "github.com/signintech/gopdf"
)

func main() {
    pdf := gopdf.GoPdf{}
    pdf.Start(gopdf.Config{ PageSize: *gopdf.PageSizeA4 }) //595.28, 841.89 = A4

    err := pdf.AddTTFFont("LiberationSerif-Regular", "./test/res/LiberationSerif-Regular.ttf")
    if err != nil {
        log.Print(err.Error())
        return
    }

    err = pdf.SetFont("LiberationSerif-Regular", "", 14)
    if err != nil {
        log.Print(err.Error())
        return
    }

    pdf.AddHeader(func() {
        pdf.SetY(5)
        pdf.Cell(nil, "header")
    })
    pdf.AddFooter(func() {
        pdf.SetY(825)
        pdf.Cell(nil, "footer")
    })

    pdf.AddPage()
    pdf.SetY(400)
    pdf.Text("page 1 content")
    pdf.AddPage()
    pdf.SetY(400)
    pdf.Text("page 2 content")

    pdf.WritePdf("header-footer.tmp.pdf")

}

Draw line
pdf.SetLineWidth(2)
pdf.SetLineType("dashed")
pdf.Line(10, 30, 585, 30)
Draw oval
pdf.SetLineWidth(1)
pdf.Oval(100, 200, 500, 500)
Draw polygon
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")
Draw rectangle with round corner
pdf.SetStrokeColor(255, 0, 0)
pdf.SetLineWidth(2)
pdf.SetFillColor(0, 255, 0)
err := pdf.Rectangle(196.6, 336.8, 398.3, 379.3, "DF", 3, 10)
if err != nil {
    return err
}
Draw rectangle with round corner using CMYK color model
pdf.SetStrokeColorCMYK(88, 49, 0, 0)
pdf.SetLineWidth(2)
pdf.SetFillColorCMYK(0, 5, 89, 0)
err := pdf.Rectangle(196.6, 336.8, 398.3, 379.3, "DF", 3, 10)
if err != nil {
    return err
}
Rotation text or image
pdf.SetXY(100, 100)
pdf.Rotate(270.0, 100.0, 100.0)
pdf.Text("Hello...")
pdf.RotateReset() //reset
Set transparency
Read about transparency in pdf (page 320, section 11)

// alpha - value of transparency, can be between `0` and `1`
// blendMode - default value is `/Normal` - read about [blendMode and kinds of its](https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf) `(page 325, section 11.3.5)`

transparency := Transparency{
    Alpha: 0.5,
    BlendModeType: "",
}
pdf.SetTransparency(transparency Transparency)
Password protection
package main

import (
    "log"

    "github.com/signintech/gopdf"
)


func main() {

    pdf := gopdf.GoPdf{}
    pdf.Start(gopdf.Config{
        PageSize: *gopdf.PageSizeA4, //595.28, 841.89 = A4
        Protection: gopdf.PDFProtectionConfig{
            UseProtection: true,
            Permissions: gopdf.PermissionsPrint | gopdf.PermissionsCopy | gopdf.PermissionsModify,
            OwnerPass:   []byte("123456"),
            UserPass:    []byte("123456789")},
    })

    pdf.AddPage()
    pdf.AddTTFFont("loma", "../ttf/loma.ttf")
    pdf.Cell(nil,"Hi")
    pdf.WritePdf("protect.pdf")
}

Import existing PDF

Import existing PDF power by package gofpdi created by @phpdave11 (thank you :smile:)

package main

import (
        "github.com/signintech/gopdf"
        "io"
        "net/http"
        "os"
)

func main() {
        var err error

        // Download a Font
        fontUrl := "https://github.com/google/fonts/raw/master/ofl/daysone/DaysOne-Regular.ttf"
        if err = DownloadFile("example-font.ttf", fontUrl); err != nil {
            panic(err)
        }

        // Download a PDF
        fileUrl := "https://tcpdf.org/files/examples/example_012.pdf"
        if err = DownloadFile("example-pdf.pdf", fileUrl); err != nil {
            panic(err)
        }

        pdf := gopdf.GoPdf{}
        pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4

        pdf.AddPage()

        err = pdf.AddTTFFont("daysone", "example-font.ttf")
        if err != nil {
            panic(err)
        }

        err = pdf.SetFont("daysone", "", 20)
        if err != nil {
            panic(err)
        }

        // Color the page
        pdf.SetLineWidth(0.1)
        pdf.SetFillColor(124, 252, 0) //setup fill color
        pdf.RectFromUpperLeftWithStyle(50, 100, 400, 600, "FD")
        pdf.SetFillColor(0, 0, 0)

        pdf.SetXY(50, 50)
        pdf.Cell(nil, "Import existing PDF into GoPDF Document")

        // Import page 1
        tpl1 := pdf.ImportPage("example-pdf.pdf", 1, "/MediaBox")

        // Draw pdf onto page
        pdf.UseImportedTemplate(tpl1, 50, 100, 400, 0)

        pdf.WritePdf("example.pdf")

}

// DownloadFile will download a url to a local file. It's efficient because it will
// write as it downloads and not load the whole file into memory.
func DownloadFile(filepath string, url string) error {
        // Get the data
        resp, err := http.Get(url)
        if err != nil {
            return err
        }
        defer resp.Body.Close()

        // Create the file
        out, err := os.Create(filepath)
        if err != nil {
            return err
        }
        defer out.Close()

        // Write the body to file
        _, err = io.Copy(out, resp.Body)
        return err
}

Possible to set Trim-box

package main

import (
    "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)

    if err := pdf.AddTTFFont("wts11", "../ttf/wts11.ttf"); err != nil {
        log.Print(err.Error())
        return
    }

    if err := pdf.SetFont("wts11", "", 14); err != nil {
        log.Print(err.Error())
        return
    }

    pdf.Cell(nil,"Hi")
    pdf.WritePdf("hello.pdf")
}

visit https://github.com/oneplus1000/gopdfsample for more samples.

案例演示

func (l *GuitarPdfLogic) GuitarPdf(req *types.GuitarPdfReq, w http.ResponseWriter) (resp *types.GuitarPdfResp, err error) {
    // 1. 初始化pdf参数
    pdf := gopdf.GoPdf{}
    pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})
    pageHeight := gopdf.PageSizeA4.H
    pageWeight := gopdf.PageSizeA4.W
    borderTop := 50.0
    borderBottom := 50.0

    // 初始化行高,列宽
    rowHeight := 20.0
    columnWidths := []float64{50, 50, 50, 50, 50, 50, 50, 50}

    // 2.字体配置
    ariblkFont := l.ut.ObjPath.GetStaticPwd([]string{"ariblk.ttf"})
    err = pdf.AddTTFFont("ariblk", ariblkFont)
    if err != nil {
        logx.Error(err.Error())
        return nil, err
    }

    err = pdf.SetFont("ariblk", "", 10)
    if err != nil {
        logx.Error(err.Error())
        return nil, err
    }

    // 3.页眉
    pdf.AddHeader(func() {
        pdf.SetXY(pageWeight/2, borderTop/2)
        // 画图
        pdf.Image(l.ut.ObjPath.GetStaticPwd([]string{"aliyun.PNG"}), pageHeight/4, borderTop/2, &gopdf.Rect{W: 30, H: 20})
        pdf.Cell(nil, "----header---")
    })

    // 4.页尾
    pdf.AddFooter(func() {
        pdf.SetXY(pageWeight/2, pageHeight-(borderBottom/2))
        pdf.Cell(nil, "----footer----")
    })

    pdf.AddPage()
    // 5.表格绘制
    var rowCount int
    pdf.SetY(borderTop)
    for i := 0; i < 50; i++ {
        // 获取当前所在位置高度
        nowHeight := pdf.GetY()

        // 获取下一行的高度
        nextRowHeight := nowHeight + rowHeight // 假设下一行高度比当前行高度多2mm

        if nextRowHeight > (pageHeight - float64(borderBottom)) {
            // 如果下一行的高度超过了当前页面的剩余空间,则添加新页面
            pdf.AddPage()
            pdf.SetY(borderTop)
        }

        // 在新的一行开始
        pdf.Br(rowHeight)
        // 在每一列添加单元格
        for _, width := range columnWidths {
            // 添加单元格
            pdf.CellWithOption(&gopdf.Rect{
                W: width,
                H: rowHeight,
            }, fmt.Sprintf("%d,%d", i+1, rowCount), gopdf.CellOption{Align: gopdf.Center | gopdf.Middle})
        }
    }

    // 写入http
    n, err := pdf.WriteTo(w)
    logx.Error(n)
    if err != nil {
        return nil, err
    }
    return
}