利用golang实现pdf中自动换行的表格

 更新时间:2024年02月02日 10:18:58   作者:HardCorePlayer  
这篇文章主要给大家介绍了如何利用golang实现pdf中自动换行的表格,文中通过代码示例给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

需要用到的库:jung-kurt/gofpdf

由于CellFormat方法不支持\n换行,会被变成乱码,MultiCell方法会自动将坐标定位到下一行。所以需要自己实现坐标的计算变换。通过Rect方法画出单元格,MultiCell方法在格内自动换行写字,在计算坐标重复写单元格,最终组成一行。

参考ExampleFpdf_Rect()

实现自动换行的表格

import "github.com/jung-kurt/gofpdf"


type pdfLine struct {
	pdf      *gofpdf.Fpdf
	h        float64	// 需要的行高
	x        float64	// 记录开始时坐标
	y        float64	// 记录开始时坐标
	style    string		// 风格  F仅填充 D仅边框 或者DF两个都要
	alignStr string		// 对其方式 LCR为水平的左、中、右,TMBA为垂直的上、中、下、基准线
	fontH    float64	// 字体高度
	cells    []pdfCell	// 
}

type pdfCell struct {
	w      float64	// 宽度
	h      float64	// 行高
	txtStr string	// 文本
	lines  int		// 判断文本会占几行
}

func (s *pdfLine) addLine(style string, alignStr string, cells ...pdfCell) {
	s.style = style
	s.alignStr = alignStr
	_, s.fontH = s.pdf.GetFontSize()
	// 记录需要的最高行高
	for _, cell := range cells {
		lines := s.pdf.SplitText(cell.txtStr, cell.w)
		h := float64(len(lines)) * cell.h
		if s.h < h {
			s.h = h
		}
		cell.lines = len(lines)
		s.cells = append(s.cells, cell)
	}
	_, _, _, mbottom := s.pdf.GetMargins() // 获取当前页面边距
	_, pageh := s.pdf.GetPageSize()        // 获取当前页面尺寸
	x, y := s.pdf.GetXY()                  // 获取当前位置
	// 页面剩余行高不够时 开启新一页
	if s.pdf.GetY()+s.h > pageh-mbottom {
		s.pdf.AddPage()
		y = s.pdf.GetY()
	}
	s.x = x
	s.y = y
	s.write()
}

// 写入
func (s *pdfLine) write() {
	x := s.x
	y := s.y
	// 手动记录并移动坐标
	for _, c := range s.cells {
		usedH := float64(c.lines) * s.fontH
		margin := (s.h - usedH) / 2.0
		s.pdf.Rect(x, s.y, c.w, s.h, s.style)
		s.pdf.SetXY(x, y+margin) // 保持单元格内的文字有边距
		s.pdf.MultiCell(c.w, s.fontH, c.txtStr, "", s.alignStr, false)
		x += c.w
		s.pdf.SetXY(x, y)
	}
	// 坐标重置为下一行的当前位置
	s.pdf.SetXY(s.x, s.y+s.h)
	// 重置变量
	s.cells = nil
	s.h = 0
}

// 使用  生成一个每行4列的表格
func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	pdf.AddUTF8Font("NotoSansSC-Regular", "", "src/font/NotoSansSC-Regular.ttf")
	pdf.SetFont("NotoSansSC-Regular", "", 12)
	myPdf := pdfLine{pdf: pdf}

	width, _ := pdf.GetPageSize()		// 页面宽度
	left, _, right, _ := pdf.GetMargins()	// 左右边距
	usable := width - left - right	// 可用的页面宽度
	_,h := pdf.GetFontSize()	// 字体高度
	tableH := h + 2	// 行高  多出2mm的边距
	tableWidth := usable / 4	// 每个单元个的宽度
	pdf.SetFillColor(233, 233, 233)
	// 表头
	myPdf.addLine("FD", "CM", []pdfCell{
			{w: tableWidth, h: tableH, txtStr: "表头1"},
			{w: tableWidth, h: tableH, txtStr: "表头2"},
			{w: tableWidth, h: tableH, txtStr: "表头3"},
			{w: tableWidth, h: tableH, txtStr: "表头4"},
		}...)
	// 内容
	myPdf.addLine("", "CM", []pdfCell{
			{w: tableWidth, h: tableH, txtStr: "内容1"},
			{w: tableWidth, h: tableH, txtStr: "假设这里是很长很长的内容,你可以自己替换一下"},
			{w: tableWidth, h: tableH, txtStr: "内容3"},
			{w: tableWidth, h: tableH, txtStr: "内容4"},
		}...)
}

创建页面、指定字体

	// 添加页面
	pdf.AddPage()
	// 加载字体
	pdf.AddUTF8Font("NotoSansSC-Regular", "", "src/font/NotoSansSC-Regular.ttf")
	// 设置字体
	pdf.SetFont("NotoSansSC-Regular", "", 12)

加载字体时,会将前面New方法指定的目录和AddUTF8Font方法指定的目录文件拼在一起。

其他常用写入方法

	// 简单单元格,接收参数为 1.单元格长度  2.行高  3.文本
	pdf.Cell(cellWeight, h, "my text")
	// 自动换行的单元格,调用这个方法之左边会回到下一行的开头
	pdf.MultiCell(0, h, "假设这是一个很长的单元格")
	// 设置填充颜色
	pdf.SetFillColor(233, 233, 233)
	// 指定格式的单元格  参数 1.单元格长度 2.行高 3.文本 4.边框形式(1全边框、或者LTRB分别代表左上右下) 5.单元格
	// 写入之后的坐标(1为下一行开头,2当前坐标的下一行) 6.对其方式(LCR为水平的左、中、右,TMBA为垂直的上、中、
	// 下、基准线) 7.是否填充当前格子 8.连接 9.连接url
	pdf.CellFormat(tableWidth, tableH, "总成本", "1", 0, "M", true, 0, "")
	// 插入图片 参数分别为  1图片位置 2x坐标 3y坐标 4图片宽度 5图片高度
	pdf.ImageOptions("src/font/logo.png", width-right-25, 5, 25, 0, false, opt, 0, "")

到此这篇关于利用golang实现pdf中自动换行的表格的文章就介绍到这了,更多相关golang pdf表格自动换行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言Mock使用基本指南详解

    Go语言Mock使用基本指南详解

    这篇文章主要介绍了Go语言Mock使用基本指南详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Golang并发编程重点讲解

    Golang并发编程重点讲解

    这篇文章主要介绍了Golang并发编程,在许多环境中,实现对共享变量的正确访问所需要的微妙之处使并发编程变得困难。Go鼓励一种不同的方法,在这种方法中,共享值在通道中传递,实际上,从不由单独的执行线程主动共享
    2023-04-04
  • golang实现ip访问限制及提交次数

    golang实现ip访问限制及提交次数

    在 Web 应用中,通常会需要对 IP 访问进行限制以及控制提交次数,本文将使用中间件或者基于 Redis 这样的缓存服务来实现,感兴趣的可以了解下
    2024-10-10
  • Go语言使用组合的思想实现继承

    Go语言使用组合的思想实现继承

    这篇文章主要为大家详细介绍了在 Go 里面如何使用组合的思想实现“继承”,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,需要的可以了解一下
    2022-12-12
  • Go中数组传参的几种方式小结

    Go中数组传参的几种方式小结

    本文主要介绍了Go中数组传参的几种方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Go sync WaitGroup使用深入理解

    Go sync WaitGroup使用深入理解

    这篇文章主要为大家介绍了Go sync WaitGroup使用深入理解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Golang的关键字defer的使用方法

    Golang的关键字defer的使用方法

    这篇文章主要介绍了Golang的关键字defer的使用方法,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-06-06
  • Go语言之io.ReadAtLeast函数的基本使用和原理解析

    Go语言之io.ReadAtLeast函数的基本使用和原理解析

    io.ReadAtLeast函数是Go语言标准库提供的一个工具函数,能够从数据源读取至少指定数量的字节数据到缓冲区中,这篇文章主要介绍了io.ReadAtLeast函数的相关知识,需要的朋友可以参考下
    2023-07-07
  • go test 命令示例详解

    go test 命令示例详解

    go test是Go用来执行测试函数(test function)、基准函数(benchmark function)和示例函数(example function)的命令,这篇文章主要介绍了go test 命令,需要的朋友可以参考下
    2023-11-11
  • Golang的引用类型和指针的使用与区别

    Golang的引用类型和指针的使用与区别

    本文详细介绍了Golang中的引用类型和指针的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02

最新评论