在日常开发中,从 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 文档中所有表格的数据,输出到控制台:
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],如果单元格内容较多,会遗漏后续段落。更稳妥的做法是遍历所有段落:
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 中:
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 个表格的上限通常够用。建议在正式集成前先确认目标文档的实际表格数量。
到此这篇关于c#从word文档中提取表格数据的常见方法详解的文章就介绍到这了,更多相关c#提取word表格数据内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论