如何使用C#和OpenXml读取docx文件表格单元格中mergefield的内容
读取docx表格单元格中MergeField内容的解决方法
原有代码仅读取了单元格第一段第一个Run下的普通Text节点,而MergeField(合并域)在OOXML结构中属于
FieldCode类节点,填充后的域值通常存储在域分隔符FieldChar(类型为Separate)之后的Run节点中,部分已锁定/更新后的合并域也可能直接展开为普通文本,需要全量遍历单元格内的所有文本相关节点才能完整提取内容。
你可以使用如下兼容普通文本和合并域内容的通用提取方法:
using DocumentFormat.OpenXml.Wordprocessing; using System.Linq; using System.Text; // 提取任意TableCell内的所有文本(包含合并域填充后的内容) public string GetCellAllText(TableCell cell) { StringBuilder sb = new StringBuilder(); // 遍历单元格内所有段落 foreach (var paragraph in cell.Elements<Paragraph>()) { bool isInFieldValue = false; foreach (var child in paragraph.ChildElements) { // 处理域字符标记 if (child is FieldChar fieldChar) { if (fieldChar.FieldCharType == FieldCharValues.Separate) isInFieldValue = true; if (fieldChar.FieldCharType == FieldCharValues.End) isInFieldValue = false; continue; } // 跳过域代码部分 if (child is FieldCode) continue; // 读取普通文本和域值部分的文本 if (child is Run run) { foreach (var textElem in run.Elements<Text>()) { sb.Append(textElem.Text); } } // 兼容单元格内软换行 if (child is Break) sb.AppendLine(); } } return sb.ToString().Trim(); }
调用方式替换原有逻辑即可:
Table table = wordprocessingDocument.MainDocumentPart.Document.Body.Elements<Table>().First(); TableRow row = table.Elements<TableRow>().ElementAt(i); TableCell cell = row.Elements<TableCell>().ElementAt(j); // 直接调用方法获取单元格内容,自动兼容普通文本和MergeField填充内容 string cellContent = GetCellAllText(cell);
- 如果需要读取未填充模板的MergeField域名,可删除跳过
FieldCode节点的逻辑,直接提取FieldCode的文本内容后截取MERGEFIELD后的字段名即可。 - 该方法同时兼容单元格内多段落、多Run、软换行等常见格式,提取结果与Word客户端显示的内容一致。
内容的提问来源于stack exchange,提问作者Imyna
相关产品推荐
相关产品推荐

