利用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表格自动换行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang gorm 操作mysql及gorm基本用法

    golang gorm 操作mysql及gorm基本用法

    golang 官方的那个操作mysql的有点麻烦所以就使用了gorm,下面就gorm的使用做下简单介绍,感兴趣的朋友跟随小编一起看看吧
    2018-11-11
  • 使用Go语言实现一个简单的无界资源池

    使用Go语言实现一个简单的无界资源池

    本文我们希望通过go语言实现一个简单的资源池,而这个资源池的资源包括但不限于数据库连接池,线程池,协程池,网络连接池,只要这些资源实现我们指定的关闭方法,则都可以通过我们封装的资源池进行统一管理,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2024-05-05
  • Golang实现自定义时间结构体并支持Json&Gorm

    Golang实现自定义时间结构体并支持Json&Gorm

    因为时区等问题,很多项目需要自定义时区和时间格式,所以这篇文章主要为大家介绍了Golang如何实现自定义时间结构体并支持Json&Gorm,希望对大家有所帮助
    2024-03-03
  • Go语言内置包的使用

    Go语言内置包的使用

    本文主要介绍了Go语言内置包的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Go语言基础单元测试与性能测试示例详解

    Go语言基础单元测试与性能测试示例详解

    这篇文章主要为大家介绍了Go语言基础单元测试与性能测试示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助祝大家多多进步
    2021-11-11
  • golang三元表达式的使用方法

    golang三元表达式的使用方法

    这篇文章主要介绍了golang三元表达式的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • GoLand编写 TCP 端口扫描器的详细过程

    GoLand编写 TCP 端口扫描器的详细过程

    TCP,也就是传输控制协议(Transmission Control Protocol),这篇文章主要介绍了Go语言(Golang)编写 TCP 端口扫描器,需要的朋友可以参考下
    2023-05-05
  • go性能分析工具pprof的用途及使用详解

    go性能分析工具pprof的用途及使用详解

    刚开始接触go就遇到了一个内存问题,在进行内存分析的时候发现了一下比较好的工具,在此留下记录,下面这篇文章主要给大家介绍了关于go性能分析工具pprof的用途及使用的相关资料,需要的朋友可以参考下
    2023-01-01
  • 详解go语言中并发安全和锁问题

    详解go语言中并发安全和锁问题

    这篇文章主要介绍了go语言中并发安全和锁问题,包含互斥锁解锁过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • golang数据结构之golang稀疏数组sparsearray详解

    golang数据结构之golang稀疏数组sparsearray详解

    这篇文章主要介绍了golang数据结构之golang稀疏数组sparsearray的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09

最新评论