[C#] How to Create New Word Documents and Write Text Using OpenXML SDK

目次

Overview

This implementation creates .docx Word files in environments where Microsoft Word is not installed (such as servers or Linux). Using the “OpenXML SDK” provided by Microsoft, we programmatically construct the Word document structure—comprising the Document, Body, Paragraph, Run, and Text elements—to output text.


Specifications (Input/Output)

  • Input: Destination file path, text to be written.
  • Output: A .docx file.
  • Library: DocumentFormat.OpenXml (NuGet package).

Implemented Methods

Method NameDescription
AppendParagraphBasic implementation that creates and adds a Paragraph, Run, and Text in sequence.
AppendParagraph2A shorthand implementation that adds a paragraph concisely using nested constructors.

Basic Usage

First, install the NuGet package:

dotnet add package DocumentFormat.OpenXml

Example usage of the implemented class:

// Initialize instance with file path
using var doc = new MyWordDoc("Report.docx");

// Write using the standard method
doc.AppendParagraph("This is the first paragraph.");

// Write using the shorthand method
doc.AppendParagraph2("This is the next paragraph, written concisely.");

Full Code Example

The following code demonstrates how to wrap OpenXML SDK functionality for document generation.

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}");

            // Ensure Dispose (Save/Close) via the using statement
            using (var doc = new MyWordDoc(filePath))
            {
                doc.AppendParagraph("[Daily Report] Today's Work Summary");
                doc.AppendParagraph("Today, I implemented the basic logic for OpenXML SDK.");
                
                doc.AppendParagraph2("Progress is on track.");
                doc.AppendParagraph2("Regards.");
            }

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

/// <summary>
/// Class for creating Word documents using OpenXML SDK
/// </summary>
public sealed class MyWordDoc : IDisposable
{
    private WordprocessingDocument _document;
    private Body _body;

    // Initialize document structure in the constructor
    public MyWordDoc(string filePath)
    {
        // 1. Create WordprocessingDocument (File creation)
        _document = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document);

        // 2. Add MainDocumentPart (The primary part of the document)
        MainDocumentPart mainPart = _document.AddMainDocumentPart();

        // 3. Create the Document tree
        mainPart.Document = new Document();

        // 4. Create Body (Main content area) and add to Document
        _body = mainPart.Document.AppendChild(new Body());
    }

    // Standard method (Clear structural representation)
    public void AppendParagraph(string text)
    {
        // Create Paragraph
        Paragraph para = _body.AppendChild(new Paragraph());

        // Create Run and add to Paragraph
        // Note: A Run represents a region with specific formatting (font, color, etc.)
        Run run = para.AppendChild(new Run());

        // Create Text and add to Run
        run.AppendChild(new Text(text));
    }

    // Concise method (Using nested constructors)
    public void AppendParagraph2(string text)
    {
        // Generate Paragraph > Run > Text as a batch and add to Body
        _body.AppendChild(
            new Paragraph(
                new Run(
                    new Text(text)
                )
            )
        );
    }

    // Resource release and saving
    public void Dispose()
    {
        // Changes are committed to the file when Disposed (or Closed)
        _document?.Dispose();
    }
}

Customization Points

  • Applying Styles: To make text bold or change colors, set RunProperties on the Run object.C#var runProps = new RunProperties(); runProps.Append(new Bold()); // Bold runProps.Append(new Color() { Val = "FF0000" }); // Red run.RunProperties = runProps;
  • Inserting Page Breaks: To force a page break, add new Break() { Type = BreakValues.Page } inside a Paragraph.

Important Notes

  • Hierarchical Understanding: OpenXML strictly enforces a hierarchy of Body > Paragraph > Run > Text. You cannot add Text directly to the Body; you must follow this nested structure.
  • Necessity of Dispose: The WordprocessingDocument writes XML data to the file and completes the save only when Dispose() (or Close()) is called. Without the using block, the file may be corrupted or result in a 0-byte size.
  • File Access Conflicts: If the target file is currently open in Microsoft Word, an IOException will occur. Ensure the file is closed before execution.

Advanced Usage

Implementing Text Replacement

This example shows how to replace specific placeholders (e.g., {DATE}) within a template file.

public void ReplaceText(string placeholder, string value)
{
    // Search for all text elements within the document body
    foreach (var text in _body.Descendants<Text>())
    {
        if (text.Text.Contains(placeholder))
        {
            text.Text = text.Text.Replace(placeholder, value);
        }
    }
}

Conclusion

Using the OpenXML SDK, you can generate documents quickly and safely without depending on the Word application. While the structure may appear verbose at first, understanding the relationship between the Paragraph and the Run allows you to encapsulate methods for intuitive document manipulation.

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

この記事を書いた人

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

目次