Golang PDF导出(支持中文)

时间:2024-03-16 09:50:18

gopdf 介绍

gopdf 是一个比较完善的PDF导出库, 它整合了第三方库, 更加方便用户开发和使用. 它有以下特点:

  • 支持 Unicode 字符 (包括中文, 日语, 朝鲜语, 等等.)
  • PDF 文档自动分页
  • PDF 文档自动换行
  • PDF 文档自动化全局定位, 不需要用户去手动定位
  • PDF 默认的配置选项简单, 且已经内置了常用的几种方式
  • PDF 文档采用类似 html 页面的属性设置, 通俗易懂
  • PDF 支持图片插入, 格式可以是PNG或者JPEG, 图片会进行适当压缩
  • PDF 支持文档压缩
  • PDF 转换单位内置处理
  • Executor 可以嵌套使用

github链接是: https://www.github.com/tiechui1994/gopdf

案例展示

const (
	TABLE_IG = "IPAexG"
	TABLE_MD = "MPBOLD"
	TABLE_MY = "微软雅黑"
)

func ManyTableReportWithData() {
	r := core.CreateReport()
	font1 := core.FontMap{
		FontName: TABLE_IG,
		FileName: "example//ttf/ipaexg.ttf",
	}
	font2 := core.FontMap{
		FontName: TABLE_MD,
		FileName: "example//ttf/mplus-1p-bold.ttf",
	}
	font3 := core.FontMap{
		FontName: TABLE_MY,
		FileName: "example//ttf/microsoft.ttf",
	}
	r.SetFonts([]*core.FontMap{&font1, &font2, &font3})
	r.SetPage("A4", "mm", "P")

	r.RegisterExecutor(core.Executor(ManyTableReportWithDataExecutor), core.Detail)

	r.Execute("many_table_data.pdf")
	r.SaveAtomicCellText("many_table_data.txt")
}

func ManyTableReportWithDataExecutor(report *core.Report) {
	unit := report.GetUnit()

	lineSpace := 0.01 * unit
	lineHeight := 2 * unit

	rows, cols := 800, 5
	table := NewTable(cols, rows, 80*unit, lineHeight, report)
	table.SetMargin(core.Scope{0, 0, 0, 0})

	for i := 0; i < rows; i += 5 {
		key := rand.Intn(3)
		//key := (i+1)%2 + 1
		f1 := core.Font{Family: TABLE_MY, Size: 10}
		border := core.NewScope(0.5*unit, 0.5*unit, 0, 0)

		switch key {
		case 0:
			for row := 0; row < 5; row++ {
				for col := 0; col < cols; col++ {
					conent := fmt.Sprintf("%v-(%v,%v)", 0, i+row, col)
					cell := table.NewCell()
					txt := NewTextCell(table.GetColWidth(i+row, col), lineHeight, lineSpace, report)
					txt.SetFont(f1).SetBorder(border).SetContent(conent + GetRandStr(1))
					cell.SetElement(txt)
				}
			}

		case 1:
			c00 := table.NewCellByRange(1, 5)
			c01 := table.NewCellByRange(2, 2)
			c03 := table.NewCellByRange(2, 3)
			c21 := table.NewCellByRange(2, 1)
			c31 := table.NewCellByRange(4, 1)
			c41 := table.NewCellByRange(4, 1)

			t00 := NewTextCell(table.GetColWidth(i+0, 0), lineHeight, lineSpace, report)
			t01 := NewTextCell(table.GetColWidth(i+0, 1), lineHeight, lineSpace, report)
			t03 := NewTextCell(table.GetColWidth(i+0, 3), lineHeight, lineSpace, report)
			t21 := NewTextCell(table.GetColWidth(i+2, 1), lineHeight, lineSpace, report)
			t31 := NewTextCell(table.GetColWidth(i+3, 1), lineHeight, lineSpace, report)
			t41 := NewTextCell(table.GetColWidth(i+4, 1), lineHeight, lineSpace, report)

			t00.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 1, i+0, 0) + GetRandStr(5))
			t01.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 1, i+0, 1) + GetRandStr(4))
			t03.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 1, i+0, 3) + GetRandStr(6))
			t21.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 1, i+2, 1) + GetRandStr(2))
			t31.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 1, i+3, 1) + GetRandStr(4))
			t41.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 1, i+4, 1) + GetRandStr(4))

			c00.SetElement(t00)
			c01.SetElement(t01)
			c03.SetElement(t03)
			c21.SetElement(t21)
			c31.SetElement(t31)
			c41.SetElement(t41)

		case 2:
			c00 := table.NewCellByRange(3, 2)
			c03 := table.NewCellByRange(2, 3)
			c20 := table.NewCellByRange(1, 2)
			c21 := table.NewCellByRange(2, 3)
			c33 := table.NewCellByRange(2, 2)
			c40 := table.NewCellByRange(1, 1)

			t00 := NewTextCell(table.GetColWidth(i+0, 0), lineHeight, lineSpace, report)
			t03 := NewTextCell(table.GetColWidth(i+0, 3), lineHeight, lineSpace, report)
			t20 := NewTextCell(table.GetColWidth(i+2, 0), lineHeight, lineSpace, report)
			t21 := NewTextCell(table.GetColWidth(i+2, 1), lineHeight, lineSpace, report)
			t33 := NewTextCell(table.GetColWidth(i+3, 3), lineHeight, lineSpace, report)
			t40 := NewTextCell(table.GetColWidth(i+4, 0), lineHeight, lineSpace, report)

			t00.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 2, i+0, 0) + GetRandStr(6))
			t03.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 2, i+0, 3) + GetRandStr(6))
			t20.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 2, i+2, 0) + GetRandStr(2))
			t21.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 2, i+2, 1) + GetRandStr(6))
			t33.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 2, i+3, 3) + GetRandStr(4))
			t40.SetFont(f1).SetBorder(border).SetContent(fmt.Sprintf("%v-(%v,%v)", 2, i+4, 0) + GetRandStr(1))

			c00.SetElement(t00)
			c03.SetElement(t03)
			c20.SetElement(t20)
			c21.SetElement(t21)
			c33.SetElement(t33)
			c40.SetElement(t40)
		}

	}

	table.GenerateAtomicCell()
}


func GetRandStr(l ...int) string {
	seed := rand.New(rand.NewSource(time.Now().UnixNano()))
	str := "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ"
	l = append(l, 8)
	r := seed.Intn(l[0]*11) + 8
	data := strings.Repeat(str, r/36+1)
	return data[:r] + "---"
}

func TestTable(t *testing.T) {
	ManyTableReportWithData()
}

上述的案例展示的是一个复杂不规则的案例, 效果图如下
Golang PDF导出(支持中文)

跟多案例请参考其库…