go无原生word支持,生成.docx必须用第三方库:unidoc/unioffice写入需商业许可,go-docx(mit协议)适合简单报告;注意样式在run级设置、表格需addparagraph、保存用savetofile,模板填充不健壮。

Go 语言没有原生 Word 支持,docx 必须靠第三方库
Go 标准库不提供任何文档格式(.docx、.xlsx)处理能力,所有“生成 Word”的操作都依赖外部库。目前最成熟、维护活跃的是 unidoc/unioffice 和 tealeg/xlsx(后者只做 Excel),而真正专注 .docx 的主力是 unidoc/unioffice ——但它分免费版和商业版:免费版仅支持读取,**写入/生成必须用商业许可证**。
如果你只是想快速生成简单报告、导出文本内容,更现实的选择是:go-docx(MIT 协议,纯 Go 实现,支持基础段落、表格、样式)或 godoct(轻量,但 API 不稳定)。别被“Go 操作 Word”这类标题误导,没许可证、没选对库,Save() 会直接 panic 或静默失败。
-
unidoc/unioffice免费版调用document.Save()会报错:license required for writing -
go-docx不支持页眉页脚、复杂样式继承、OLE 对象 - 所有库都不支持 VBA、宏、嵌入字体,也几乎不兼容 Word 的自动编号逻辑
用 go-docx 生成基础 Word 文档的最小可行路径
它适合生成日志摘要、API 响应快照、测试报告这类结构扁平、无需排版精度的文档。核心流程是:创建文档 → 添加段落/表格 → 保存。不涉及模板、不解析现有 docx,纯从零构建。
安装:go get github.com/nguyenthenguyen/docx(注意作者名拼写,不是 go-docx)
- 段落加粗要用
Run().AddText().Bold(true),不是Paragraph().Bold(true)—— 样式作用在 Run 级别,不是 Paragraph - 表格单元格内容必须用
Cell().AddParagraph().AddRun().AddText(),漏掉AddParagraph()会导致空白单元格 - 中文正常显示,但默认字体是 Calibri;如需宋体,得显式设置:
Run().Font("SimSun") - 保存前必须调用
docx.SaveToFile("report.docx"),只调Save()会写入内存缓冲,不落地
doc := docx.NewDocument()
p := doc.AddParagraph()
p.AddRun().AddText("Hello, 世界!").Bold(true)
doc.SaveToFile("hello.docx")
unidoc/unioffice 写入失败的三个典型错误信号
即使你买了许可证,unioffice 的写入链路长、中间态多,出错时往往不报具体原因。遇到以下现象,优先检查对应环节:
- 程序卡住或 CPU 飙高:大概率是文档对象未关闭,漏了
document.Close()—— 它内部有 sync.Pool 和 goroutine 调度,不 Close 可能阻塞 - 生成的
.docx打不开,提示“文件已损坏”:常见于未设置文档类型,必须在创建后立即调用document.SetType(document.DocumentTypeDocument) - 样式全丢失、文字堆成一团:没调
document.UpdateFields()或document.UpdateTableOfContents()(即使没目录,也要调,否则段落间距失效)
另外,unioffice 默认用 zip.Writer 打包,若磁盘空间不足或路径含中文,SaveToFile() 可能静默失败 —— 建议先 SaveToZipWriter() 到 bytes.Buffer,再写文件,便于捕获 error。
别碰“动态模板填充”这种需求,除非你接受严重妥协
Word 用户习惯的“{{name}} 替换”式模板,在 Go 里没有健壮方案。所有现有库对段落内占位符的定位都基于纯文本匹配,一旦用户在 Word 里加了空格、换行、隐藏字符,或用了不同 Run 分段,替换就失效。
更麻烦的是样式继承:一个 {{date}} 被替换成 “2024-06-12” 后,新文本不会自动继承原文本的字号、颜色、加粗状态 —— 你得手动遍历原 Run 的所有属性再复制过去,代码量爆炸且极易漏。
-
go-docx完全不提供查找替换 API,只能自己遍历document.Paragraphs和Run.Text()字符串匹配 -
unioffice有document.FindText(),但返回的是只读TextRange,不能直接修改样式或内容 - 真要模板,建议降级:用 Markdown 生成 +
pandoc转 docx(命令行调用),或前端用docxtemplater(JS)生成,Go 只负责数据接口
Word 的二进制结构和样式模型,跟 Go 的内存模型、文本处理惯性根本不匹配。越想“完全模拟 Word 操作”,越容易陷入边界 case 的泥潭。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











