利用golang實現(xiàn)pdf中自動換行的表格
需要用到的庫:jung-kurt/gofpdf
由于CellFormat方法不支持\n換行,會被變成亂碼,MultiCell方法會自動將坐標(biāo)定位到下一行。所以需要自己實現(xiàn)坐標(biāo)的計算變換。通過Rect方法畫出單元格,MultiCell方法在格內(nèi)自動換行寫字,在計算坐標(biāo)重復(fù)寫單元格,最終組成一行。
實現(xiàn)自動換行的表格
import "github.com/jung-kurt/gofpdf" type pdfLine struct { pdf *gofpdf.Fpdf h float64 // 需要的行高 x float64 // 記錄開始時坐標(biāo) y float64 // 記錄開始時坐標(biāo) style string // 風(fēng)格 F僅填充 D僅邊框 或者DF兩個都要 alignStr string // 對其方式 LCR為水平的左、中、右,TMBA為垂直的上、中、下、基準(zhǔn)線 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() // 獲取當(dāng)前頁面邊距 _, pageh := s.pdf.GetPageSize() // 獲取當(dāng)前頁面尺寸 x, y := s.pdf.GetXY() // 獲取當(dāng)前位置 // 頁面剩余行高不夠時 開啟新一頁 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 // 手動記錄并移動坐標(biāo) 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) // 保持單元格內(nèi)的文字有邊距 s.pdf.MultiCell(c.w, s.fontH, c.txtStr, "", s.alignStr, false) x += c.w s.pdf.SetXY(x, y) } // 坐標(biāo)重置為下一行的當(dāng)前位置 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"}, }...) // 內(nèi)容 myPdf.addLine("", "CM", []pdfCell{ {w: tableWidth, h: tableH, txtStr: "內(nèi)容1"}, {w: tableWidth, h: tableH, txtStr: "假設(shè)這里是很長很長的內(nèi)容,你可以自己替換一下"}, {w: tableWidth, h: tableH, txtStr: "內(nèi)容3"}, {w: tableWidth, h: tableH, txtStr: "內(nèi)容4"}, }...) }
創(chuàng)建頁面、指定字體
// 添加頁面 pdf.AddPage() // 加載字體 pdf.AddUTF8Font("NotoSansSC-Regular", "", "src/font/NotoSansSC-Regular.ttf") // 設(shè)置字體 pdf.SetFont("NotoSansSC-Regular", "", 12)
加載字體時,會將前面New方法指定的目錄和AddUTF8Font方法指定的目錄文件拼在一起。
其他常用寫入方法
// 簡單單元格,接收參數(shù)為 1.單元格長度 2.行高 3.文本 pdf.Cell(cellWeight, h, "my text") // 自動換行的單元格,調(diào)用這個方法之左邊會回到下一行的開頭 pdf.MultiCell(0, h, "假設(shè)這是一個很長的單元格") // 設(shè)置填充顏色 pdf.SetFillColor(233, 233, 233) // 指定格式的單元格 參數(shù) 1.單元格長度 2.行高 3.文本 4.邊框形式(1全邊框、或者LTRB分別代表左上右下) 5.單元格 // 寫入之后的坐標(biāo)(1為下一行開頭,2當(dāng)前坐標(biāo)的下一行) 6.對其方式(LCR為水平的左、中、右,TMBA為垂直的上、中、 // 下、基準(zhǔn)線) 7.是否填充當(dāng)前格子 8.連接 9.連接url pdf.CellFormat(tableWidth, tableH, "總成本", "1", 0, "M", true, 0, "") // 插入圖片 參數(shù)分別為 1圖片位置 2x坐標(biāo) 3y坐標(biāo) 4圖片寬度 5圖片高度 pdf.ImageOptions("src/font/logo.png", width-right-25, 5, 25, 0, false, opt, 0, "")
到此這篇關(guān)于利用golang實現(xiàn)pdf中自動換行的表格的文章就介紹到這了,更多相關(guān)golang pdf表格自動換行內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang實現(xiàn)ip訪問限制及提交次數(shù)
在?Web?應(yīng)用中,通常會需要對?IP?訪問進行限制以及控制提交次數(shù),本文將使用中間件或者基于?Redis?這樣的緩存服務(wù)來實現(xiàn),感興趣的可以了解下2024-10-10Go語言之io.ReadAtLeast函數(shù)的基本使用和原理解析
io.ReadAtLeast函數(shù)是Go語言標(biāo)準(zhǔn)庫提供的一個工具函數(shù),能夠從數(shù)據(jù)源讀取至少指定數(shù)量的字節(jié)數(shù)據(jù)到緩沖區(qū)中,這篇文章主要介紹了io.ReadAtLeast函數(shù)的相關(guān)知識,需要的朋友可以參考下2023-07-07