如何用C#的DocumentFormat.OpenXml获取Word图表内嵌矩形的txBody?
问题
我有一个带图表的Word文档,图表里有两个矩形,需要获取它们的txBody来修改文本。已知信息:
- 图表rId为17
- 图表Uri为
/word/charts/chart2.xml(DrawingML格式) - ChartDrawingPart的Uri为
/word/drawings/drawing1.xml,其中包含目标txBody:
<cdr:txBody> <a:bodyPr xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" vertOverflow="clip" lIns="54000" rIns="54000"/> <a:lstStyle xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"/> <a:p xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"> <a:pPr algn="ctr"/> <a:r> <a:rPr lang="da-DK"/> <a:t>BB</a:t> </a:r> </a:p> </cdr:txBody>
只要能通过C#的DocumentFormat.OpenXml获取这个txBody,就能修改其中文本。
我已经能修改文档中的段落、内容控件、图表和表格,但找不到指定图表里的矩形。尝试过以下方法(doc为WordprocessingDocument实例):
遍历doc.MainDocumentPart?.ChartParts能找到chart2.xml并修改数值,但找不到矩形;还尝试过:
doc.MainDocumentPart.Document.Descendants<Drawing>() doc.MainDocumentPart.Document.Descendants<UserShapes>() doc.MainDocumentPart.Document.Descendants<DocumentFormat.OpenXml.Drawing.Shape>() doc.MainDocumentPart.Document.Descendants<Chart>() doc.MainDocumentPart.Document.Descendants<ExternalData>() doc.MainDocumentPart?.ImageParts doc.MainDocumentPart?.DiagramDataParts
以及类似:
chartSpaceChildElem.Descendants<DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing.TxPrTextBody>()
这些都没获取到目标内容。我认为可以访问MainDocumentPart下的document、comments等元素,但无法访问/word/drawings/下的drawing1.xml?
需要用C#的DocumentFormat.OpenXml获取该txBody,不想通过流处理XML(不需要解压Word文档)。
解决方法
要访问drawing1.xml对应的ChartDrawingPart,需先找到关联的ChartPart,再通过ChartPart获取其ChartDrawingParts。具体实现代码如下:
using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Drawing; using DocumentFormat.OpenXml.Drawing.Charts; // 引入别名避免命名空间冲突 using A = DocumentFormat.OpenXml.Drawing; using Cdr = DocumentFormat.OpenXml.Drawing.Charts; // 假设doc是已打开的WordprocessingDocument实例 var mainPart = doc.MainDocumentPart; // 1. 通过rId="17"定位目标ChartPart var chartPart = (ChartPart)mainPart.GetPartById("rId17"); // 2. 获取对应的ChartDrawingPart(即/word/drawings/drawing1.xml) var chartDrawingPart = chartPart.ChartDrawingParts.FirstOrDefault(); if (chartDrawingPart != null) { // 3. 加载ChartDrawingPart的根元素 var chartDrawing = chartDrawingPart.ChartDrawing; // 4. 遍历所有形状,提取txBody并修改文本 foreach (var shape in chartDrawing.Descendants<Cdr.Shape>()) { var txBody = shape.TxBody; if (txBody != null) { // 找到所有文本节点并修改 foreach (var textElement in txBody.Descendants<A.Text>()) { // 替换原有文本,示例改为"新文本内容" textElement.Text = "新文本内容"; } } } // 保存ChartDrawingPart的修改 chartDrawingPart.ChartDrawing.Save(); } // 保存整个Word文档 doc.Save();
关键说明
- ChartDrawingPart是ChartPart的子部件,不能直接从MainDocumentPart获取,必须通过对应ChartPart关联访问
- 注意区分命名空间:
DocumentFormat.OpenXml.Drawing.Charts(别名Cdr)下的Shape和TxBody对应图表中的绘图元素,不要和普通文档形状的命名空间混淆 - 修改完成后需分别保存ChartDrawingPart和整个文档
内容的提问来源于stack exchange,提问作者ChrKT
相关产品推荐
相关产品推荐

