Golang PDF导出(多语言)

gopdf 介绍

简介: PDF 是一种常用的文档格式, 在目前的很多流行语言都已经实现了生成PDF文档库. Go是一门新兴特别受欢迎的语言, 虽然目前也存在一些开源的库支持生成PDF文件, 但是都存在一些问题, 有的库只支持英文, 有的库是虽然支持中文, 但是提供的接口很难用. gopdf 的主要就是提供一套既支持中文, 又相对好用的接口的方案.

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

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

github链接是: https://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()
}

上述的案例展示的是一个复杂不规则的案例, 效果图如下
在这里插入图片描述

未来计划

  1. 打算开发 Markdown 转 PDF 部分
  2. 优化组件

更新详细使用, 请参考开源库 https://github.com/tiechui1994/gopdf, 欢迎大家贡献自己的力量.

感谢大家的支持, 欢迎关注公众号 “后端开发杂谈”, 每天领取新文章.
在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值