如何使用 Spire.Doc 在 C# 中创建、写入和读取 Word 文档?

如何使用 Spire.Doc 在 C# 中创建、写入和读取 Word 文档?

在日常开发中,动态生成报告、合同等Word文档是常见需求。使用Spire.Doc for .NET,无需依赖Office组件,即可通过C#代码高效完成文档的创建、内容写入和数据读取,轻松实现自动化文档处理。本文将分享具体实现方法。


1. Spire.Doc 简介与环境配置

Spire.Doc 是一款专业的 .NET Word 组件,专为在 .NET 应用程序中快速、高质量地处理 Word 文档而设计。

  • 无需 Office:完全独立的组件,不依赖 Microsoft Office。
  • 功能强大:支持创建、编辑、转换 Word 文档,涵盖文本、图片、表格、图表、邮件合并、书签、表单域等几乎所有 Word 元素。
  • 高性能:优化了文档处理算法,在大文档和批量处理场景下表现出色。
  • 跨平台:支持 .NET Framework、.NET Core、.NET 5/6/7 等多种 .NET 平台,可在 Windows、Linux、macOS 等系统上运行。
  • 多种格式支持:支持 DOC、DOCX、RTF、XML、TXT、HTML、ODT、OTT 等多种 Word 格式。

环境配置

使用 Spire.Doc 非常简单,只需通过 NuGet 包管理器安装即可。

  1. 在 Visual Studio 中打开你的项目。
  2. 右键点击项目 -> "管理 NuGet 包"。
  3. 在"浏览"选项卡中搜索 Spire.Doc
  4. 点击"安装"按钮,等待安装完成。

安装完成后,在 C# 代码中引入必要的命名空间:

csharp 复制代码
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System.Drawing; // 用于颜色和图片
using System.IO;      // 用于文件操作

2. 创建与写入 Word 文档

现在,让我们通过具体的代码示例,学习如何使用 Spire.Doc 创建并向 Word 文档中写入内容。

创建新的 Word 文档

实例化 Document 对象即可创建一个空白的 Word 文档:

csharp 复制代码
// 创建一个新的 Word 文档
Document document = new Document();
// 添加一个节 (Section),所有内容都必须添加到节中
Section section = document.AddSection();

添加段落与文本

Word 文档由段落组成,每个段落可以包含文本、图片等元素。

csharp 复制代码
// 添加一个段落
Paragraph paragraph1 = section.AddParagraph();
// 向段落中添加文本
TextRange textRange1 = paragraph1.AppendText("这是使用 Spire.Doc 创建的第一个段落。");

// 设置文本格式
textRange1.CharacterFormat.FontName = "微软雅黑";
textRange1.CharacterFormat.FontSize = 14;
textRange1.CharacterFormat.TextColor = Color.DarkBlue;
textRange1.CharacterFormat.Bold = true;

// 添加另一个段落,并设置右对齐
Paragraph paragraph2 = section.AddParagraph();
paragraph2.AppendText("这是一个右对齐的段落。");
paragraph2.Format.HorizontalAlignment = Spire.Doc.Documents.HorizontalAlignment.Right;

插入图片与表格

Spire.Doc 同样支持插入图片和创建表格。

插入图片

csharp 复制代码
// 添加一个段落用于插入图片
Paragraph imageParagraph = section.AddParagraph();
// 插入本地图片
DocPicture picture = imageParagraph.AppendPicture(Image.FromFile("your_image.png"));
// 设置图片大小 (可选)
picture.Width = 150;
picture.Height = 100;

创建与填充表格

API 方法 描述
section.AddTable() 在节中添加一个表格
table.AddRow() 向表格中添加行
row.Cells[index] 获取指定索引的单元格
cell.AddParagraph() 向单元格中添加段落
paragraph.AppendText() 向段落中添加文本
csharp 复制代码
// 添加一个表格
Table table = section.AddTable();
// 设置表格的列数和默认行高
table.ResetCells(3, 3); // 3行3列
table.DefaultRowHeight = 25;
table.TableFormat.Borders.BorderType = BorderStyle.Single; // 设置边框

// 填充表格内容
for (int r = 0; r < table.Rows.Count; r++)
{
    TableRow row = table.Rows[r];
    for (int c = 0; c < row.Cells.Count; c++)
    {
        TableCell cell = row.Cells[c];
        // 设置单元格背景色 (可选)
        if (r == 0)
        {
            cell.CellFormat.Shading.BackgroundPatternColor = Color.LightGray;
        }
        // 添加内容到单元格
        Paragraph cellParagraph = cell.AddParagraph();
        cellParagraph.AppendText($"单元格 ({r + 1}, {c + 1})");
        cellParagraph.Format.HorizontalAlignment = Spire.Doc.Documents.HorizontalAlignment.Center;
        cellParagraph.Format.VerticalAlignment = VerticalAlignment.Middle;
    }
}

保存文档

完成内容写入后,将文档保存到指定路径:

csharp 复制代码
// 保存文档为 DOCX 格式
document.SaveToFile("MyWordDocument.docx", FileFormat.Docx);

// 也可以保存为 DOC 格式
// document.SaveToFile("MyWordDocument.doc", FileFormat.Doc);

// 关闭文档
document.Close();

3. 读取 Word 文档内容

Spire.Doc 不仅能创建文档,也能轻松读取现有 Word 文档中的内容。

加载现有文档

csharp 复制代码
// 加载一个已存在的 Word 文档
Document document = new Document();
document.LoadFromFile("MyWordDocument.docx");

遍历文档内容

Word 文档的结构通常是 Document -> Section -> Body -> Paragraph/Table。我们可以通过循环遍历来访问各个元素。

csharp 复制代码
// 遍历文档中的所有节
foreach (Section section in document.Sections)
{
    // 遍历节中的所有段落
    foreach (DocumentObject obj in section.Body.ChildObjects)
    {
        if (obj.DocumentObjectType == DocumentObjectType.Paragraph)
        {
            Paragraph paragraph = obj as Paragraph;
            Console.WriteLine($"段落文本: {paragraph.Text}");

            // 遍历段落中的所有子对象 (TextRange, Picture 等)
            foreach (DocumentObject paraChild in paragraph.ChildObjects)
            {
                if (paraChild.DocumentObjectType == DocumentObjectType.TextRange)
                {
                    TextRange textRange = paraChild as TextRange;
                    Console.WriteLine($"  文本片段: {textRange.Text}");
                }
                else if (paraChild.DocumentObjectType == DocumentObjectType.Picture)
                {
                    DocPicture picture = paraChild as DocPicture;
                    Console.WriteLine($"  图片文件: {picture.ImageBytes.Length} 字节");
                }
            }
        }
        else if (obj.DocumentObjectType == DocumentObjectType.Table)
        {
            Table table = obj as Table;
            Console.WriteLine("发现表格:");
            // 遍历表格的行和单元格
            foreach (TableRow row in table.Rows)
            {
                foreach (TableCell cell in row.Cells)
                {
                    Console.Write($"  单元格内容: {cell.Text.Trim()} |");
                }
                Console.WriteLine();
            }
        }
    }
}

提取特定信息

Spire.Doc 提供了强大的查找替换功能,可以用于提取特定文本。

csharp 复制代码
// 根据关键字查找文本
TextSelection[] selections = document.FindAllString("Spire.Doc", true, true);
if (selections != null)
{
    foreach (TextSelection selection in selections)
    {
        // 获取找到的文本及其所在段落
        Console.WriteLine($"找到关键字: '{selection.SelectedText}',位于段落: '{selection.Get  As One Paragraph().Text}'");
    }
}

// 读取表格单元格内容 (假设我们知道表格和单元格的索引)
// 假设这是文档中的第一个表格
Table firstTable = document.Sections[0].Body.Tables[0] as Table;
if (firstTable != null && firstTable.Rows.Count > 1 && firstTable.Rows[0].Cells.Count > 0)
{
    // 读取第二行第一列的文本
    string cellContent = firstTable.Rows[1].Cells[0].Text.Trim();
    Console.WriteLine($"表格中的特定单元格内容 (第二行第一列): {cellContent}");
}

4. 进阶技巧与注意事项

Spire.Doc 的功能远不止于此,它还提供了许多高级特性,可以满足更复杂的 Word 文档处理需求:

  • 合并文档:将多个 Word 文档合并成一个。
  • 查找替换:支持正则表达式查找和替换。
  • 书签操作:创建、查找和更新书签内容。
  • 表单域:创建和填充 Word 表单域。
  • 转换格式:将 Word 文档转换为 PDF、HTML、图片等格式。
  • 文档属性:读写文档的元数据,如作者、标题等。

性能优化

当处理大型文档或进行大量文档操作时,可以考虑以下优化:

  • 批量操作:尽可能利用 Spire.Doc 提供的批量操作 API。
  • 内存管理 :及时释放不再使用的 Document 对象,避免内存泄漏。
  • 文件流操作 :在读取/写入文件时,使用 Stream 可以更灵活地控制内存。
相关推荐
Victor3561 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端
缘不易1 小时前
Springboot 整合JustAuth实现gitee授权登录
spring boot·后端·gitee
Kiri霧1 小时前
Range循环和切片
前端·后端·学习·golang
WizLC1 小时前
【Java】各种IO流知识详解
java·开发语言·后端·spring·intellij idea
Victor3561 小时前
Netty(19)Netty的性能优化手段有哪些?
后端
爬山算法1 小时前
Netty(15)Netty的线程模型是什么?它有哪些线程池类型?
java·后端
白宇横流学长2 小时前
基于SpringBoot实现的冬奥会科普平台设计与实现【源码+文档】
java·spring boot·后端
Python编程学习圈2 小时前
Asciinema - 终端日志记录神器,开发者的福音
后端
bing.shao3 小时前
Golang 高并发秒杀系统踩坑
开发语言·后端·golang
壹方秘境3 小时前
一款方便Java开发者在IDEA中抓包分析调试接口的插件
后端