如何用 C# 读取 Word 中的表格数据

在日常开发中,从 Word 文档中提取表格数据是一个高频需求------无论是数据导入、报表迁移,还是将合同中的结构化信息入库。手动复制粘贴效率低下,调用 Office COM 组件又面临环境依赖和版本兼容问题。本文介绍一种轻量方案:使用 Free Spire.Doc for .NET 在 C# 中读取 Word 表格数据。

说明:Free Spire.Doc 是 Spire.Doc 的免费社区版,无需安装 Microsoft Word,支持 .doc 和 .docx 格式的读写。安装方式:Install-Package FreeSpire.Doc


核心对象模型

Free Spire.Doc 解析 Word 表格时,文档的层级结构如下:

对象 对应结构 获取方式
Document 整个 Word 文档 new Document() + LoadFromFile()
Section 文档中的"节" doc.Sections[i]
Table 表格 section.Tables[i]
TableRow 表格行 table.Rows[i]
TableCell 单元格 row.Cells[i]
Paragraph 单元格内的段落 cell.Paragraphs[i]

核心遍历路径是:Document → Section → Table → Row → Cell → Paragraph。一个文档可以包含多个节,每个节可以包含多个表格。


基础读取代码

以下代码读取 Word 文档中所有表格的数据,输出到控制台:

csharp 复制代码
using Spire.Doc;
using System;

namespace ReadWordTable
{
    class Program
    {
        static void Main(string[] args)
        {
            Document doc = new Document();
            doc.LoadFromFile(@"E:\sample.docx");

            foreach (Section section in doc.Sections)
            {
                foreach (Table table in section.Tables)
                {
                    Console.WriteLine("=== 表格开始 ===");
                    foreach (TableRow row in table.Rows)
                    {
                        foreach (TableCell cell in row.Cells)
                        {
                            string cellText = cell.Paragraphs[0].Text.Trim();
                            Console.Write(cellText + "\t");
                        }
                        Console.WriteLine();
                    }
                }
            }

            doc.Close();
        }
    }
}

这段代码的逻辑是:加载文档后,依次遍历每个节的每个表格,再逐行逐单元格提取文本,用制表符分隔单元格、换行符分隔行。


几个容易被忽略的细节

单元格包含多个段落时只取第一段会丢数据。 Word 表格的一个单元格内可能有多个段落(例如多行说明文字)。上面的基础代码只读取了 Paragraphs[0],如果单元格内容较多,会遗漏后续段落。更稳妥的做法是遍历所有段落:

csharp 复制代码
string cellText = "";
for (int i = 0; i < cell.Paragraphs.Count; i++)
{
    cellText += cell.Paragraphs[i].Text.Trim() + " ";
}
cellText = cellText.Trim();

合并单元格在遍历时会出现重复内容。 当表格中存在水平或垂直合并的单元格时,TableRow.Cells 的索引可能对应到同一个逻辑单元格对象。遍历时如果直接按索引读取,合并区域的数据会被重复提取。实践中需要根据业务需求判断是否对合并单元格做去重处理,或者使用库提供的合并信息判断方法。

嵌套表格需要递归处理。 如果单元格内嵌入了另一个表格,上面的遍历不会进入嵌套表格。此时需要检查 cell.ChildObjects,找出其中类型为 Table 的对象并递归遍历。


提取到文本文件的完整写法

将每个表格保存为独立的文本文件,单元格用制表符分隔,行用换行符分隔,可以直接粘贴到 Excel 中:

csharp 复制代码
using Spire.Doc;
using Spire.Doc.Collections;
using System.IO;
using System.Text;

namespace ExtractWordTable
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Document doc = new Document();
            doc.LoadFromFile("表格.docx");

            for (int sectionIndex = 0; sectionIndex < doc.Sections.Count; sectionIndex++)
            {
                Section section = doc.Sections[sectionIndex];
                TableCollection tables = section.Tables;

                for (int tableIndex = 0; tableIndex < tables.Count; tableIndex++)
                {
                    ITable table = tables[tableIndex];
                    string tableData = "";

                    for (int rowIndex = 0; rowIndex < table.Rows.Count; rowIndex++)
                    {
                        TableRow row = table.Rows[rowIndex];

                        for (int cellIndex = 0; cellIndex < row.Cells.Count; cellIndex++)
                        {
                            TableCell cell = row.Cells[cellIndex];
                            string cellText = "";

                            for (int paraIndex = 0; paraIndex < cell.Paragraphs.Count; paraIndex++)
                            {
                                cellText += cell.Paragraphs[paraIndex].Text.Trim() + " ";
                            }

                            tableData += cellText.Trim();
                            if (cellIndex < row.Cells.Count - 1)
                                tableData += "\t";
                        }
                        tableData += "\n";
                    }

                    string filePath = Path.Combine(
                        "Tables",
                        $"Section{sectionIndex + 1}_Table{tableIndex + 1}.txt");
                    Directory.CreateDirectory("Tables");
                    File.WriteAllText(filePath, tableData, Encoding.UTF8);
                }
            }
            doc.Close();
        }
    }
}

这份代码将每个表格保存为 Tables/Section1_Table1.txt 等文件,单元格间用 \t 分隔,行末用 \n 结束,输出格式兼容 Excel 的直接粘贴。


免费版限制提醒

Free Spire.Doc 免费版在读取文档时存在硬性限制:单个文档最多处理 500 个段落和 25 个表格。该限制在读取文件时即被强制执行,超出部分的表格数据不会被加载。

对于大多数中小型场景------比如从合同模板、配置表、简单的数据报表中提取表格------25 个表格的上限通常够用。建议在正式集成前先确认目标文档的实际表格数量。

相关推荐
郝学胜-神的一滴1 小时前
C++20模板元编程 04:变量模板 别名模板与模板Lambda实战
服务器·开发语言·数据结构·c++·程序人生
驭渊的小故事1 小时前
Java 项目-jckson序列化工具
java·开发语言
君顾11 小时前
上海24小时自助健身房系统开发实战指南:从架构设计到功能实现
java·开发语言·健身房
qq_344920562 小时前
Qt事件过滤器
开发语言·c++·qt
执明wa2 小时前
Android RecyclerView 多类型, 多种 Item
android·xml·开发语言·设计模式·android studio
程序员yu2 小时前
数智码力:Python作用域完全梳理,全局变量局部变量不再混乱
开发语言·python·学习
阿松爱学习3 小时前
【Unity开发】FileStream 详解及用法指南
unity·c#·unity开发
不灭的黄金瞳1233 小时前
Java数据类型与变量
java·开发语言·intellij-idea