Dot-Net
使用 OpenXML 替換 word 文件中的圖像
繼我的最後一個問題之後
OpenXML 看起來可能正是我想要的,但是文件很糟糕。一個小時的Google搜尋並沒有讓我更接近於弄清楚我需要做什麼。
我有一個word文件。我想以這樣一種方式將圖像添加到該 word 文件(使用 word),然後我可以在 OpenXML 中打開該文件並替換該圖像。應該很簡單吧?
我假設我應該能夠為我的圖像“佔位符”提供某種 id,然後使用
GetPartById它來定點陣圖像並替換它。這會是正確的方法嗎?這個 ID 是什麼?你如何使用Word添加它?我能找到的每個範例都可以從頭開始在 ML 中建構整個 word 文件,這實際上並沒有太多用處。
**編輯:**在我看來,將媒體文件夾中的圖像替換為新圖像會更容易,但再次找不到任何有關如何執行此操作的指示。
儘管 OpenXML 的文件不是很好,但有一個出色的工具可以用來查看現有 Word 文件是如何建構的。如果您安裝 OpenXml SDK,它會附帶Open XML 格式 SDK\V2.0\tools目錄下的DocumentReflector.exe工具。
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();