golang pdf 导出实践
18 Nov 2021温馨提示:仅为个人笔记以免遗忘,不保证代码完整
Maroto 可以类似与 bootstrap 这样的前端库一样对 pdf 页面布局排版,使用行、列和组件来构建 pdf 文档,也可以支持图片、二维码等
在项目目录下,引入依赖:
go get -u github.com/johnfercher/maroto
go get github.com/johnfercher/maroto/internal@v0.31.0
go get github.com/brianvoe/gofakeit/v6
示例代码:
main.go
package main
import (
"fmt"
"os"
"github.com/johnfercher/maroto/pkg/color"
"github.com/johnfercher/maroto/pkg/consts"
"github.com/johnfercher/maroto/pkg/pdf"
"github.com/johnfercher/maroto/pkg/props"
"github.com/divrhino/fruitful-pdf/data"
)
func main() {
m := pdf.NewMaroto(consts.Portrait, consts.A4)
m.AddUTF8Font("NotoSansSC", "", "./fonts/NotoSansSC-Regular.ttf")
m.AddUTF8Font("NotoSansSC", "I", "./fonts/NotoSansSC-Regular.ttf")
m.AddUTF8Font("NotoSansSC", "B", "./fonts/NotoSansSC-Regular.ttf")
m.AddUTF8Font("NotoSansSC", "BI", "./fonts/NotoSansSC-Regular.ttf")
m.SetPageMargins(20, 10, 20)
buildHeading(m)
buildGroupHeader(m, "基础信息")
buildBaseInfo(m)
buildGroupHeader(m, "土地信息")
buildLandInfo(m)
buildGroupHeader(m, "宗地信息")
buildFruitList(m)
buildGroupHeader(m, "土地规划")
buildImage(m, "images/001.png")
err := m.OutputFileAndClose("pdfs/001.pdf")
if err != nil {
fmt.Println("⚠️ Could not save PDF:", err)
os.Exit(1)
}
fmt.Println("PDF saved successfully")
}
func buildHeading(m pdf.Maroto) {
m.RegisterHeader(func() {
m.Row(20, func() {
m.Col(12, func() {
err := m.FileImage("images/logo.png", props.Rect{
Center: true,
Percent: 55,
})
if err != nil {
fmt.Println("Image file was not loaded 😱 - ", err)
}
})
})
m.Row(10, func() {
m.Col(12, func() {
m.Text("大宗物业交易平台", props.Text{
Size: 12.0,
Top: 3.0,
Family: "NotoSansSC",
Style: consts.BoldItalic,
Align: consts.Center,
Color: getDarkPurpleColor(),
})
})
})
})
}
// 头部
func buildGroupHeader(m pdf.Maroto, name string) {
m.Row(10, func() {
m.Col(1, func() {
m.Text(name, props.Text{
Top: 5,
Family: "NotoSansSC",
Style: consts.BoldItalic,
Align: consts.Left,
Color: getTealColor(),
})
})
})
m.Line(1.0)
}
func buildBaseInfo(m pdf.Maroto) {
m.Row(10, func() {
buildFormItem(m, "城区:", "宝安区")
buildFormItem(m, "片区:", "宝安中心")
})
m.Row(10, func() {
buildFormLine(m, "地址:", "西安市周至县振兴北路金凤幼,儿园西北侧约150米")
})
}
func buildLandInfo(m pdf.Maroto) {
m.Row(10, func() {
buildFormItem(m, "土地来源:", "深圳经济发展公司签订租赁")
buildFormItem(m, "土地性质:", "住宅-R0")
})
m.Row(10, func() {
buildFormLine(m, "土地使用年限:", "50 年,2001 年 01 月 24 日 - 2032 年 03 月 20 日")
})
m.Row(10, func() {
buildFormLine(m, "土地用途:", "厂房出租")
})
}
// 列
func buildFormItem(m pdf.Maroto, label, text string) {
m.Col(2, func() {
m.Text(label, props.Text{
// Size: 10.0,
Style: consts.BoldItalic,
Family: "NotoSansSC",
Align: consts.Left,
Top: 3.0,
Extrapolate: false,
Color: color.Color{
Red: 10,
Green: 20,
Blue: 30,
},
})
})
m.Col(4, func() {
m.Text(text, props.Text{
Top: 3,
Family: "NotoSansSC",
Align: consts.Left,
Color: getDarkPurpleColor(),
})
})
}
// 整行
func buildFormLine(m pdf.Maroto, label, text string) {
m.Col(2, func() {
m.Text(label, props.Text{
// Size: 10.0,
Style: consts.BoldItalic,
Family: "NotoSansSC",
Align: consts.Left,
Top: 3.0,
Extrapolate: false,
Color: color.Color{
Red: 10,
Green: 20,
Blue: 30,
},
})
})
m.Col(10, func() {
m.Text(text, props.Text{
Family: "NotoSansSC",
Align: consts.Left,
Top: 3,
Extrapolate: false,
VerticalPadding: 1.0,
Color: getDarkPurpleColor(),
})
})
}
func buildFruitList(m pdf.Maroto) {
tableHeadings := []string{"宗地号", "占地面积", "有证占地面积", "无证占地面积", "建筑面积", "有证建筑面积", "无证建筑面积", "建筑现状"}
contents := data.FruitList(5)
lightPurpleColor := getLightPurpleColor()
m.SetBackgroundColor(color.NewWhite())
m.TableList(tableHeadings, contents, props.TableList{
HeaderProp: props.TableListContent{
Size: 8,
Family: "NotoSansSC",
GridSizes: []uint{1, 1, 2, 2, 1, 2, 2, 1},
},
ContentProp: props.TableListContent{
Size: 7,
Family: "NotoSansSC",
GridSizes: []uint{1, 1, 2, 2, 1, 2, 2, 1},
},
Align: consts.Center,
AlternatedBackground: &lightPurpleColor,
HeaderContentSpace: 1,
Line: false,
})
}
func getDarkPurpleColor() color.Color {
return color.Color{
Red: 88,
Green: 80,
Blue: 99,
}
}
func getLightPurpleColor() color.Color {
return color.Color{
Red: 210,
Green: 200,
Blue: 230,
}
}
func getTealColor() color.Color {
return color.Color{
Red: 3,
Green: 166,
Blue: 166,
}
}
func buildImage(m pdf.Maroto, src string) {
m.Row(100, func() {
m.Col(12, func() {
err := m.FileImage(src, props.Rect{
Center: false,
// Percent: 100,
Top: 3,
})
if err != nil {
fmt.Println("Image file was not loaded 😱 - ", err)
}
})
})
}
导出的展示: