继我上一个问题 here
OpenXML 看起来可能正是我想要的,但文档很糟糕。一个小时的谷歌搜索并没有让我更接近于弄清楚我需要做什么。
我有一个word文档。我想以这样一种方式将图像添加到该 word 文档(使用 word),然后我可以在 OpenXML 中打开该文档并替换该图像。应该很简单吧?
我假设我应该能够为我的图像“占位符”提供某种 id,然后使用 GetPartById
找到图像并替换它。这会是正确的方法吗?这个 ID 是什么?你如何使用Word添加它?
我能找到的每个示例都可以从头开始在 ML 中构建整个 word 文档,这实际上并没有太多用处。
编辑:我突然想到,将媒体文件夹中的图像替换为新图像会更容易,但又找不到任何有关如何执行此操作的指示。
请您参考如下方法:
尽管 OpenXML 的文档不是很好,但是有一个出色的工具可以用来查看现有 Word 文档是如何构建的。如果您安装 OpenXml SDK,它会附带 DocumentReflector.exe Open XML Format SDK\V2.0\tools 目录下的工具。
Word 文档中的图像由图像数据和分配给它的 ID 组成,该 ID 在文档正文中引用。您的问题似乎可以分为两部分:查找图像的 ID 在文档中,然后 重写图像数据为了它。
要查找图像的 ID,您需要解析 MainDocumentPart。图像作为绘图元素存储在 Runs 中
<w:p>
<w:r>
<w:drawing>
<wp:inline>
<wp:extent cx="3200400" cy="704850" /> <!-- describes the size of the image -->
<wp:docPr id="2" name="Picture 1" descr="filename.JPG" />
<a:graphic>
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic>
<pic:nvPicPr>
<pic:cNvPr id="0" name="filename.JPG" />
<pic:cNvPicPr />
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId5" /> <!-- this is the ID you need to find -->
<a:stretch>
<a:fillRect />
</a:stretch>
</pic:blipFill>
<pic:spPr>
<a:xfrm>
<a:ext cx="3200400" cy="704850" />
</a:xfrm>
<a:prstGeom prst="rect" />
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
</w:r>
</w:p>
在上面的示例中,您需要找到存储在 blip 元素中的图像的 ID。如何查找取决于您的问题,但如果您知道原始图像的文件名,则可以查看 docPr 元素:
using (WordprocessingDocument document = WordprocessingDocument.Open("docfilename.docx", true)) {
// go through the document and pull out the inline image elements
IEnumerable<Inline> imageElements = from run in Document.MainDocumentPart.Document.Descendants<Run>()
where run.Descendants<Inline>().First() != null
select run.Descendants<Inline>().First();
// select the image that has the correct filename (chooses the first if there are many)
Inline selectedImage = (from image in imageElements
where (image.DocProperties != null &&
image.DocProperties.Equals("image filename"))
select image).First();
// get the ID from the inline element
string imageId = "default value";
Blip blipElement = selectedImage.Descendants<Blip>().First();
if (blipElement != null) {
imageId = blipElement.Embed.Value;
}
}
然后,当您拥有图像 ID 时,您可以使用它来重写图像数据。我认为这就是你的做法:
ImagePart imagePart = (ImagePart)document.MainDocumentPart.GetPartById(imageId);
byte[] imageBytes = File.ReadAllBytes("new_image.jpg");
BinaryWriter writer = new BinaryWriter(imagePart.GetStream());
writer.Write(imageBytes);
writer.Close();