在技术文档、代码审查记录或内部报告整理中,常需要把 Python 脚本嵌入 Word 文档。少量代码可以手动复制,但脚本较长或文件较多时,自动化方式在一致性和效率上更合适。本文围绕 Spire.Doc for Python 和 Pygments,给出两种可落地的实现:纯文本嵌入与 RTF 语法高亮嵌入,并说明关键代码、参数含义、局限和选择建议。
环境准备
实现上述功能需要两个库:Spire.Doc 负责创建和操作 Word 文档,Pygments 负责生成带语法高亮的代码格式。安装命令如下:
- pip install spire.doc pygments
复制代码
两个方案都会从 spire.doc 导入 Document、ParagraphStyle、FileFormat 等类与枚举,Pygments 相关模块只在第二个方案中使用。
方案一:纯文本嵌入
纯文本方式先读取 .py 文件内容,再插入 Word 段落,并用等宽字体保持代码缩进和可读性。它实现简单,生成的代码在 Word 中完全可编辑。
- from pathlib import Path
- from spire.doc import *
- # 读取 Python 文件
- code_string = Path("demo.py").read_text(encoding="utf-8")
- # 创建一个 Word 文档
- doc = Document()
- # 添加一个节
- section = doc.AddSection()
- section.PageSetup.Margins.All = 60
- # 添加一个段落
- paragraph = section.AddParagraph()
- # 将代码字符串插入段落
- paragraph.AppendText(code_string)
- # 创建一个段落样式
- style = ParagraphStyle(doc)
- style.Name = "code"
- style.CharacterFormat.FontName = "Consolas"
- style.CharacterFormat.FontSize = 12
- style.ParagraphFormat.LineSpacing = 12
- doc.Styles.Add(style)
- # 将样式应用于段落
- paragraph.ApplyStyle("code")
- # 保存文档
- doc.SaveToFile("Output.docx", FileFormat.Docx2019)
- doc.Dispose()
复制代码
这段代码的关键在于 ParagraphStyle 的创建与应用。等宽字体如 Consolas 是保持代码对齐的基础;固定行距,例如 LineSpacing 设为 12,可让多行代码的纵向间距一致。Path.read_text() 会原样读取文件内容,缩进、空行和换行符都会被保留。文档使用完毕后调用 Dispose() 释放资源。
需要注意,AppendText 插入的是纯文本,换行符在 Word 中表现为软换行,段落样式统一应用于整个代码块。如果代码中含有制表符,其显示宽度取决于 Word 的制表位设置,必要时可先用 expandtabs() 将制表符转为空格。
纯文本方式适合代码需要保持可编辑状态的场景,例如技术文档中读者可能要复制代码片段进行测试。它的局限也很明显:Word 中不会呈现语法着色,关键字、字符串和注释没有视觉区分,较长代码块的阅读体验一般。
方案二:Pygments 语法高亮 + RTF 嵌入
如果希望代码在 Word 中呈现类似 IDE 的着色效果,可以借助 Pygments 将代码转换为带格式的 RTF 字符串,再通过 AppendRTF 方法插入 Word。RTF 方案的一个特点是:嵌入后的代码在 Word 中仍然是可选中、可编辑的文本,而不是图片。
- from pathlib import Path
- from pygments import highlight
- from pygments.lexers import PythonLexer
- from pygments.formatters import RtfFormatter
- from spire.doc import *
- # 读取 Python 文件
- code = Path("demo.py").read_text(encoding="utf-8")
- # 设置字体
- formatter = RtfFormatter(fontface="Consolas")
- # 指定词法分析器,生成带高亮的 RTF
- rtf_text = highlight(code, PythonLexer(), formatter)
- rtf_text = rtf_text.replace(r"\f0", r"\f0\fs24") # 字体大小(24 对应 12 磅字体)
- # 创建一个 Word 文档
- doc = Document()
- # 添加一个节
- section = doc.AddSection()
- section.PageSetup.Margins.All = 60
- # 添加一个段落
- paragraph = section.AddParagraph()
- # 将语法高亮的代码作为 RTF 插入
- paragraph.AppendRTF(rtf_text)
- # 保存文档
- doc.SaveToFile("Output.docx", FileFormat.Docx2019)
- doc.Dispose()
复制代码
这里有几个细节值得说明。RtfFormatter(fontface="Consolas") 指定输出 RTF 使用的字体,与纯文本方案保持一致,避免 Word 中显示为默认替代字体。Pygments 生成的 RTF 默认字号较小,通过 replace(r"\f0", r"\f0\fs24") 在字体控制字后追加字号指令,将其调整为约 12 磅。这是一种直接操作 RTF 控制字的做法,简单有效,但该替换是全局字符串替换,若 RTF 中其他位置也出现 \f0 序列,会一并被修改;在固定字体配置下通常无碍,更换格式时需留意。PythonLexer() 负责解析 Python 语法元素,RtfFormatter 将其映射为 RTF 的颜色控制字,关键字、字符串、注释等会呈现不同颜色。
RTF 方案的格式精细程度受限于 RTF 的表达能力。如果对布局有更细致的要求,例如自定义背景色、行号显示,RTF 并非最佳载体,可考虑 HTML 嵌入或图片方案。此外,Pygments 支持通过 style 参数更换配色方案,默认样式在 Word 中的对比度通常够用,若需调整可查阅 Pygments 文档。
两种方案的对比与选择
从对比维度看,纯文本方案没有语法着色,实现复杂度低,格式控制集中在基础字体和行距;RTF 语法高亮方案有语法着色,实现复杂度中等,需要引入 Pygments,格式精细控制受限于 RTF 表达能力。
选择建议是:如果 Word 文档主要用于存档或内部传阅,且读者不需要在 Word 中直接修改代码,语法高亮方案的可读性更好;如果代码需要被频繁复制粘贴到其他环境,或者文档对文件体积敏感,纯文本方案更轻量。两者均不需要安装 Microsoft Word,可在纯 Python 环境中运行。
结语
将 Python 代码转换为 Word 文档的核心操作集中在文本读取、格式生成与文档写入三个环节。纯文本方案依靠等宽字体保证基础可读性,RTF 方案则借助 Pygments 在保持文本可编辑的前提下补足语法着色能力。实际使用时,可以根据文档目标读者和后续用途在两者之间选择。对于批量处理多个脚本文件的场景,上述逻辑同样可以封装为函数,配合目录遍历实现自动化输出。 |