必须调用pdf.addttffont加载中文字体文件(如notosanscjksc-regular.ttf),路径需绝对或通过embed嵌入,再用setfont指定注册时的逻辑字体名,缺一不可。

用 go-pdf 或 gopdf 生成基础 PDF 时,中文乱码怎么 fix
默认字体不支持中文,直接写入中文会显示方块或空白。gopdf 自带的 Helvetica 和 Courier 都是西文字体,必须显式注册中文字体文件(如 simsun.ttc 或 NotoSansCJKsc-Regular.ttf)。
- 下载一个开源中文字体(推荐
NotoSansCJKsc-Regular.ttf,Google 开源,无版权风险) - 调用
pdf.AddTTFFont()注册字体,路径必须是绝对路径或确保运行时可读(别用相对路径依赖工作目录) - 注册后用
pdf.SetFont()切换到该字体名(不是文件名),例如"NotoSansCJKsc" - 注意:字体名可能和文件内嵌名不一致,可用
fonttools工具查真实 PostScript 名,或试pdf.GetFontList()看已加载列表
gin 框架里返回 PDF 流时 Content-Type 怎么设才兼容所有浏览器
设成 application/pdf 是标准做法,但预览和下载行为取决于 Content-Disposition 头。用户点击链接是在线打开还是弹保存框,全靠这个头控制。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 在线预览:设
Content-Disposition: inline; filename="report.pdf" - 强制下载:设
Content-Disposition: attachment; filename="report.pdf" - 文件名含中文?用
filename*=UTF-8''%E6%8A%A5%E8%A1%A8.pdf编码,避免 IE/Edge 解析失败 - 别漏掉
Content-Length—— gin 默认不自动计算,手动写c.Data(status, "application/pdf", buf.Bytes())更稳,或者用c.Writer.Write()+c.Writer.Flush()
动态生成大报表(万行数据)内存爆了怎么办
gopdf 把整个文档存在内存 buffer 里,数据一多就 OOM。不能等全部写完再输出,得边生成边流式写入 HTTP 响应。
- 改用
github.com/signintech/gopdf/v3(v3 支持io.Writer接口) - 创建
http.ResponseWriter的包装器,实现io.Writer,把每页 PDF 数据块直接写入响应流 - 避免一次性加载所有数据:用分页查询 +
pdf.AddPage()分批写入,每页生成完立刻 flush - 慎用
pdf.Cell()布局复杂表格——它内部缓存整行,万行表格建议用底层pdf.Rectangle()+pdf.Text()手动定位画布
PDF 生成后校验失败或 Chrome 预览空白的常见原因
生成的 PDF 文件头损坏、交叉引用表错误、或未正确关闭文档,都会导致浏览器解析失败,表现为白屏或“无法加载 PDF”提示。
- 必须调用
pdf.Close(),否则 PDF trailer 缺失,文件不合法 - 如果用了
io.MultiWriter同时写日志和响应,确认没提前 close 或 write 超出 buffer - Chrome 有时缓存旧 PDF 响应,加
Cache-Control: no-cache, no-store, must-revalidate头 - 调试时先保存到磁盘:
os.WriteFile("debug.pdf", buf.Bytes(), 0644),用 Acrobat 或pdfinfo debug.pdf验证是否有效
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










