【C#】OpenXML SDKでWord文書を新規作成してテキストを書き込む

目次

概要

Microsoft Wordがインストールされていない環境(サーバーやLinuxなど)で、.docx 形式のWordファイルを新規作成する実装です。

Microsoftが提供する「OpenXML SDK」を使用し、Word文書の構造(Document, Body, Paragraph, Run, Text)をプログラムから構築してテキストを出力します。

仕様(入出力)

  • 入力: 保存先のファイルパス、書き込むテキスト
  • 出力: .docx ファイル
  • ライブラリ: DocumentFormat.OpenXml (NuGetパッケージ)

実装メソッド

メソッド名説明
AppendParagraph段落(Paragraph)、書式(Run)、テキスト(Text)を順に作成して追加する基本実装です。
AppendParagraph2コンストラクタのネストを利用し、1行で簡潔に段落を追加する短縮実装です。

基本の使い方

まず、NuGetパッケージをインストールします。

dotnet add package DocumentFormat.OpenXml

実装したクラスの使用例です。

// ファイルパスを指定してインスタンス生成
using var doc = new MyWordDoc("Report.docx");

// 通常のメソッドで書き込み
doc.AppendParagraph("これは最初の段落です。");

// 短縮メソッドで書き込み
doc.AppendParagraph2("これは次の段落です。簡潔に記述できます。");

コード全文

using System;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

class Program
{
    static void Main()
    {
        string filePath = "Report.docx";
        
        try
        {
            Console.WriteLine($"Creating Word document: {filePath}");

            // usingステートメントで確実にDispose(保存・クローズ)させる
            using (var doc = new MyWordDoc(filePath))
            {
                doc.AppendParagraph("【日報】本日の業務報告");
                doc.AppendParagraph("本日はOpenXML SDKの基本実装を行いました。");
                
                doc.AppendParagraph2("進捗は順調です。");
                doc.AppendParagraph2("以上、よろしくお願いいたします。");
            }

            Console.WriteLine("Document created successfully.");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}

/// <summary>
/// OpenXML SDKを使用したWord文書作成クラス
/// </summary>
public sealed class MyWordDoc : IDisposable
{
    private WordprocessingDocument _document;
    private Body _body;

    // コンストラクタでドキュメント構造を初期化
    public MyWordDoc(string filePath)
    {
        // 1. WordprocessingDocumentを作成(ファイル作成)
        _document = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document);

        // 2. MainDocumentPart(文書の主要部分)を追加
        MainDocumentPart mainPart = _document.AddMainDocumentPart();

        // 3. Documentツリーを作成
        mainPart.Document = new Document();

        // 4. Body(本文領域)を作成してDocumentに追加
        _body = mainPart.Document.AppendChild(new Body());
    }

    // 基本的な追加方法(構造が分かりやすい記述)
    public void AppendParagraph(string text)
    {
        // 段落(Paragraph)を作成
        Paragraph para = _body.AppendChild(new Paragraph());

        // 実行単位(Run)を作成して段落に追加
        // ※Runはフォントや色などの書式設定を持つ単位
        Run run = para.AppendChild(new Run());

        // テキスト(Text)を作成してRunに追加
        run.AppendChild(new Text(text));
    }

    // 簡潔な追加方法(ネストを利用した記述)
    public void AppendParagraph2(string text)
    {
        // Paragraph > Run > Text を一括で生成してBodyに追加
        _body.AppendChild(
            new Paragraph(
                new Run(
                    new Text(text)
                )
            )
        );
    }

    // リソースの解放と保存
    public void Dispose()
    {
        // CloseまたはDisposeで変更が保存される
        _document?.Dispose();
    }
}

カスタムポイント

  • スタイルの適用:文字を太字にしたり色を変えたりする場合は、Run オブジェクトに対して RunProperties を設定します。C#var runProps = new RunProperties(); runProps.Append(new Bold()); // 太字 runProps.Append(new Color() { Val = "FF0000" }); // 赤色 run.RunProperties = runProps;
  • 改ページの挿入:特定の場所でページを変えたい場合は、Paragraph 内に Break() { Type = BreakValues.Page } を追加します。

注意点

  1. 階層構造の理解:OpenXMLでは Body > Paragraph > Run > Text という階層構造が厳格に決まっています。Body に直接 Text を追加することはできず、必ずこの入れ子構造を守る必要があります。
  2. Disposeの必須性:WordprocessingDocument は Dispose()(または Close())が呼ばれたタイミングでXMLデータをファイルに書き込み、保存を完了させます。using 文を使わないと、ファイルが破損したりサイズが0バイトになったりします。
  3. ファイルアクセスの競合:作成しようとしているファイルがWordで開かれていると、IOException が発生します。実行前に必ず同名のファイルを閉じてください。

応用

テキストの置換機能の実装

テンプレートファイル内の特定の文字列(例: {DATE})を置換して保存する例です。

public void ReplaceText(string placeholder, string value)
{
    // 文書内のすべてのテキスト要素を検索
    foreach (var text in _body.Descendants<Text>())
    {
        if (text.Text.Contains(placeholder))
        {
            text.Text = text.Text.Replace(placeholder, value);
        }
    }
}

まとめ

OpenXML SDKを使用すれば、Wordアプリケーションに依存することなく、高速かつ安全にドキュメントを生成できます。構造がやや冗長に見えますが、Paragraph(段落)と Run(書式範囲)の関係を理解すれば、メソッドをカプセル化することで直感的に扱えるようになります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次