gofpdf.new() 初始化不加载字体,需显式调用addfont()或addfontfrombytes()注册truetype(.ttf)字体;中文渲染须用notosanscjksc等支持unicode bmp的开源字体,并setfont()生效。

gofpdf.New() 初始化时字体路径不生效?
默认情况下 gofpdf.New() 创建的 PDF 实例没有注册任何字体,直接调用 AddFont() 或写中文会 panic:「font not found」。这不是 bug,是 gofpdf 的设计约定——字体必须显式加载,且路径需指向真实存在的 .ttf 文件。
- Linux/macOS 下推荐用系统字体路径,比如
/System/Library/Fonts/PingFang.ttc(macOS)或/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf(Ubuntu) - Windows 下注意反斜杠转义,建议统一用正斜杠或
filepath.Join()拼接,例如"C:/Windows/Fonts/simsun.ttc" - 更稳妥的做法是把字体文件随二进制一起打包:用
embed.FS加载,再通过pdf.AddFontFromBytes()注册字节流,避免运行时路径依赖
中文内容渲染乱码或空白?
gofpdf 本身不支持 OpenType 特性(如 GSUB/GPOS),所以不能直接用 Windows 自带的 simsun.ttc 或 macOS 的 PingFang.ttc ——它们是复合字体,gofpdf 只认单体 TrueType(.ttf)且要求含完整 Unicode BMP 覆盖。常见现象是文字变方块、空格、或整段消失。
- 优先选用开源可商用字体,如
NotoSansCJKsc-Regular.ttf(简体中文)、SourceHanSansSC-Regular.otf(需先用工具转成 ttf) - 加载时必须指定字体名(第一个参数)与样式(第二个参数为空字符串表示常规),例如:
pdf.AddFont("NotoSansCJKsc", "", "fonts/NotoSansCJKsc-Regular.ttf") - 设置字体后,务必调用
pdf.SetFont("NotoSansCJKsc", "", 12),否则仍走默认 Helvetica,中文继续不可见
生成大表格时内存暴涨甚至 OOM?
gofpdf 是纯内存构建 PDF 结构,所有单元格、行高、边框样式都缓存在 gofpdf.Fpdf 实例里。用 CellFormat() 或 MultiCell() 循环画百行表格时,内部会累积大量浮点坐标计算和字符串拼接,GC 压力明显。
- 避免在循环中反复调用
SetXY()+Cell();改用Write()+ 手动换行控制位置,减少状态切换开销 - 超长文本提前截断或分页:用
GetStringWidth()预估宽度,结合GetPageWidth()和当前GetX()判断是否换行 - 导出前调用
pdf.Close()释放底层 buffer,但注意:一旦 close 就不能再写内容,别放在循环里
Web HTTP 响应中 PDF 下载失败或损坏?
典型表现是浏览器弹出下载但打开提示「文件已损坏」,或预览一片空白。根本原因常是响应头缺失、缓冲未刷新、或中间件截断了二进制流。
立即学习“go语言免费学习笔记(深入)”;
- 必须设置
Content-Type: application/pdf和Content-Disposition: attachment; filename="report.pdf"(后者决定下载名) - 写入响应体前,清空并锁定 writer 缓冲:
rw.Header().Set("Content-Transfer-Encoding", "binary"),再用pdf.Output(rw)直接输出 - 不要用
fmt.Fprintf(rw, "%s", pdf.OutputBuf())—— 这会把二进制当 UTF-8 字符串处理,破坏 PDF 签名(%PDF-1.)











