使用 OpenXML 替换 word 文档中的图像 [英] Replace image in word doc using OpenXML

查看:24
本文介绍了使用 OpenXML 替换 word 文档中的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

继我的上一个问题这里

OpenXML 看起来可能正是我想要的,但文档很糟糕.一个小时的谷歌搜索并没有让我更接近弄清楚我需要做什么.

OpenXML looks like it probably does exactly what I want, but the documentation is terrible. An hour of googling hasn't got me any closer to figuring out what I need to do.

我有一个word文档.我想将图像添加到该 word 文档(使用 word),以便我可以在 OpenXML 中打开该文档并替换该图像.应该够简单了吧?

I have a word document. I want to add an image to that word document (using word) in such a way that I can then open the document in OpenXML and replace that image. Should be simple enough, yes?

我假设我应该能够给我的图像占位符"一个某种类型的 id,然后使用 GetPartById 来定位图像并替换它.这是正确的方法吗?这个ID是什么?你如何使用 Word 添加它?

I'm assuming I should be able to give my image 'placeholder' an id of some sort and then use GetPartById to locate the image and replace it. Would this be the correct method? What is this Id? How do you add it using Word?

我能找到的每个例子都是从头开始用机器学习从头开始构建整个 word 文档,这真的没有多大用处.

Every example I can find which does anything remotely similar starts by building the whole word document from scratch in ML, which really isn't a lot of use.

我突然想到用新图像替换媒体文件夹中的图像会更容易,但同样找不到任何关于如何执行此操作的指示.

it occured to me that it would be easier to just replace the image in the media folder with the new image, but again can't find any indication of how to do this.

推荐答案

虽然 OpenXML 的文档不是很好,但是有一个很好的工具可以用来查看现有 Word 文档是如何构建的.如果您安装 OpenXml SDK,它会在 Open XML Format SDKV2.0 ools 目录下随附 DocumentReflector.exe 工具.

Although the documentation for OpenXML isn't great, there is an excellent tool that you can use to see how existing Word documents are built. If you install the OpenXml SDK it comes with the DocumentReflector.exe tool under the Open XML Format SDKV2.0 ools directory.

Word 文档中的图像由图像数据和分配给它的 ID 组成,该 ID 在文档正文中引用.看来您的问题可以分为两部分:在文档中找到图像的 ID,然后为其重新写入图像数据.

Images in Word documents consist of the image data and an ID that is assigned to it that is referenced in the body of the document. It seems like your problem can be broken down into two parts: finding the ID of the image in the document, and then re-writing the image data for it.

要查找图像的 ID,您需要解析 MainDocumentPart.图像作为绘图元素存储在 Runs 中

To find the ID of the image, you'll need to parse the MainDocumentPart. Images are stored in Runs as a Drawing element

<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 元素:

In the above example, you need to find the ID of the image stored in the blip element. How you go about finding that is dependent on your problem, but if you know the filename of the original image you can look at the docPr element:

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 时,您可以使用它来重写图像数据.我想这就是你的方式:

Then when you have the image ID, you can use that to rewrite the image data. I think this is how you would do it:

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();

这篇关于使用 OpenXML 替换 word 文档中的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆