日常の技術業務では、コードを Word 文書に整理する必要がよくあります。技術提案書の作成、テストレポートの納品、学習ノートの整理、スクリプトのソースコードのアーカイブなどが挙げられます。コードを直接 Word にコピー&ペーストすると、書式の崩れ、インデントの消失、コードを区別するスタイルがない、バッチ処理が非効率といった問題が発生しやすくなります。
Python の文書操作ライブラリを活用すれば、コードの Word への書き込み、インデントの保持、コードスタイルの設定、文書の一括生成といった流れを自動化できます。本記事では、無料ライブラリ Free Spire.Doc for Python を使ってこの機能を実装し、.py ファイルの読み込みから読みやすい Word 文書の出力まで、いくつかの異なる方法を整理します。
環境準備とライブラリの基本的な位置づけ
pip で無料版をインストールします:
pip install Spire.Doc.Free
インポート時は通常、コアモジュールと共通型を同時に読み込む必要があります:
from spire.doc import *
from spire.doc.common import *
⚠️ 無料版の絶対的な制限を事前に理解しておく必要があります:文書は最大500段落、表は25個までです。つまり、中小規模のコードファイルやコードスニペットのアーカイブに適しています。
以下は最小構成の文書作成テンプレートであり、以降のすべてのコード整形方法の基本骨格です:
doc = Document()
section = doc.AddSection()
paragraph = section.AddParagraph()
paragraph.AppendText("Hello")
doc.SaveToFile("output.docx", FileFormat.Docx2019)
doc.Dispose()
方法1:プレーンテキストを行ごとに書き込む(等幅フォント+段落書式)
最も直接的な方法は、コードファイルを行単位で読み込み、同じ段落に1行ずつ追加し、BreakType.LineBreak で改行することです。重要なのは、すべてのコード行に等幅フォント(Courier New や Consolas など)を使用することです。そうでなければ、インデントと整列が完全に崩れます。
with open("demo.py", "r", encoding="utf-8") as f:
lines = f.read().split("\n")
doc = Document()
section = doc.AddSection()
para = section.AddParagraph()
for i, line in enumerate(lines):
run = para.AppendText(line)
run.CharacterFormat.FontName = "Courier New"
run.CharacterFormat.FontSize = 10.5
if i < len(lines) - 1:
para.AppendBreak(BreakType.LineBreak)
さらに、この上で閲覧体験を最適化できます。段落に薄い灰色の背景 Color.get_WhiteSmoke() を設定したり、複数倍の行間 LineSpacingRule.Multiple を設定したり、section.PageSetup で行番号を表示して閲覧や印刷に便利にしたりできます。
✅ 利点:実装が簡単で、ソースコードの構造を完全に保持
❌ 欠点:シンタックスハイライト非対応で、長いコードの可読性はあまり高くありません
スタイルを一元管理したい場合は、ParagraphStyle でコードスタイルを事前定義し、ApplyStyle で対象段落に適用できます:
style = ParagraphStyle(doc)
style.Name = "code"
style.CharacterFormat.FontName = "Consolas"
style.CharacterFormat.FontSize = 10
doc.Styles.Add(style)
para.ApplyStyle("code")
出力イメージ:
方法2:Pygments を利用してシンタックスハイライトを実現
プレーンテキスト方式は信頼性がありますが、キーワード、文字列、コメントに色分けがありません。Pygments は Python コードをスタイル付きの中間形式に解析し、Free Spire.Doc にレンダリングさせることができます。ここでは2つの選択肢があります。
先に依存関係をインストール:
pip install Pygments
パスA:RTF 挿入(編集可能性を保持)
RTF は Word がネイティブにサポートするリッチテキスト形式です。Pygments の RtfFormatter は色とフォント制御語を含む RTF 文字列を生成し、paragraph.AppendRTF() で直接埋め込みます。出力内容は Word 内でも選択・編集可能なテキストのままで、シンタックスハイライトが保持されます。
from spire.doc import *
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import RtfFormatter
code = open("demo.py", encoding="utf-8").read()
formatter = RtfFormatter(fontface="Consolas")
rtf_text = highlight(code, PythonLexer(), formatter)
rtf_text = rtf_text.replace(r"\f0", r"\f0\fs24") # フォントサイズを約12ptに調整
doc = Document()
section = doc.AddSection()
para = section.AddParagraph()
para.AppendRTF(rtf_text)
doc.SaveToFile("highlighted.docx", FileFormat.Docx2019)
ここに1つ細かい点があります。RtfFormatter のフォントサイズ制御は RTF 制御語 \fs の変更に依存しており、\fs24 はおおよそ12ポイントのフォントに対応します。
パスB:HTML 挿入(視覚的に豊か、自動折り返し)
コードが Web コンテンツ由来の場合、または編集可能性よりもレンダリング効果を重視する場合は、まず HtmlFormatter でインラインスタイル付き HTML を生成し、paragraph.AppendHTML() で挿入できます。Free Spire.Doc は HTML 要素を Word の書式構造にマッピングし、長い行も自動的に折り返します。
from spire.doc import *
from pathlib import Path
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter
code = Path("demo.py").read_text(encoding="utf-8")
html_text = highlight(code, PythonLexer(), HtmlFormatter(full=True))
doc = Document()
section = doc.AddSection()
section.PageSetup.Margins.All = 60
para = section.AddParagraph()
para.AppendHTML(html_text)
doc.SaveToFile("code_html.docx", FileFormat.Docx2019)
doc.Dispose()
💡 選定のヒント:
- 後で Word 内でコードを修正する必要がある → RTF を優先
- 視覚表現、自動折り返しを優先 → HTML を優先
方法3:画像としてレンダリングして挿入(視覚的忠実度重視)
書式の一貫性を編集可能性より優先する場合、シンタックスハイライト後のコードを画像としてレンダリングし、文書に挿入できます。Pygments の ImageFormatter と paragraph.AppendPicture() を組み合わせれば完了です。
ImageFormatterは Pillow の描画に依存するため、事前に依存関係をインストール:pip install pillow
import textwrap
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import ImageFormatter
from spire.doc import *
# 1. Python ソースコードを読み込む
with open("demo.py", "r", encoding="utf-8") as f:
code = f.read()
# 2. 長い行の折り返しを手動で処理
def wrap_code_lines(code_text, max_width=75):
wrapped_lines = []
for line in code_text.splitlines():
if len(line) > max_width:
wrapped_lines.extend(textwrap.wrap(
line,
width=max_width,
replace_whitespace=False,
drop_whitespace=False
))
else:
wrapped_lines.append(line)
return "\n".join(wrapped_lines)
code = wrap_code_lines(code, max_width=75)
# 3. 画像を生成
formatter = ImageFormatter(
font_name="Consolas",
font_size=18,
scale=2,
image_pad=10,
line_pad=2,
background_color="#ffffff"
)
img_bytes = highlight(code, PythonLexer(), formatter)
with open("code.png", "wb") as f:
f.write(img_bytes)
# 4. Word 文書を作成
doc = Document()
section = doc.AddSection()
section.PageSetup.Margins.All = 60
# 5. 画像を挿入
paragraph = section.AddParagraph()
picture = paragraph.AppendPicture("code.png")
# 6. 画像サイズを設定
page_width = (
section.PageSetup.PageSize.Width
- section.PageSetup.Margins.Left
- section.PageSetup.Margins.Right
)
picture.Width = page_width
# 7. Word 文書を保存
doc.SaveToFile("code_image.docx", FileFormat.Docx2019)
doc.Dispose()
- ✅ 利点:Word のバージョンやローカルフォントの影響を受けず、スタイルが完全に安定して統一される
- ❌ 欠点:コードを検索・コピー・編集できず、長いコードは折り返しの追加処理が必要。最終版文書や短いコードスニペットに適している
📊 方法の比較とまとめ
3つの方法は、編集可能性、視覚表現、実装の複雑さにおいてそれぞれトレードオフがあります:
| 方法 | シンタックスハイライト | 編集可能性 | 改行処理 | 適用シーン |
|---|---|---|---|---|
| プレーンテキストを行ごとに書き込み | なし | 完全に編集可能 | 自前で処理が必要 | 迅速なアーカイブ、複雑度の低いシーン |
| Pygments + RTF | あり | 編集可能 | 自前で処理が必要 | ハイライトを保持し、後で修正が必要 |
| Pygments + HTML | あり | 部分的に編集可能 | 自動折り返し | レンダリング効果と改行処理を追求 |
| Pygments + 画像 | あり | 編集不可 | ソフト改行が必要 | 短いスニペット、最終版文書、書式の一貫性を優先 |
🔍 選択時に主に考慮する3点:コード規模が無料版の段落上限に近いか、後でコード内容を修正する必要があるか、長い行や中国語の文字に特別な処理が必要か。これらの境界を理解すれば、日常の技術文書におけるコード埋め込み要件はほぼカバーできます。
まとめ
Python コードを Word 文書に変換する方法に唯一の最適解はありません。プレーンテキストを行ごとに書き込む方法は、迅速なアーカイブと複雑度の低いシーンに適しています。Pygments + RTF は編集可能性とシンタックスハイライトの間で良好なバランスを取っています。HTML パスは最も滑らかな改行とレンダリング効果を提供します。画像方法は編集可能性を犠牲にして絶対的な視覚的忠実性を得ます。無料版の段落上限とフォント依存を理解し、コード規模と後続用途に応じて対応する方法を選択すれば、日常の技術文書におけるコード埋め込み要件はほぼカバーできます。



