使用OpenXML SDK删除标头中的图像

时间:2017-04-10 10:11:58

标签: c# openxml openxml-sdk

我在OpenXML SDK上做了一些工作,并制作了一个替换word文档标题中的图像的POC。但是,当我尝试使用我想删除的图片调用DeletePart或DeleteParts时,它并没有按预期运行。

当我之后打开单词doc时,之前有一个图像,现在有一个带有文本的框架"此图像当前无法显示"和一个红十字会。

通过谷歌搜索,看起来似乎没有完全删除引用,但我无法找到任何帮助,如何做到这一点..

以下是我如何删除图片的示例。我只将其中一些添加到列表中,因为我需要删除除特定uri之外的所有内容..

//...

foreach(HeaderPart headerPart in document.MainDocumentPart.HeaderParts) {

    List<ImagePart> list = new List<ImagePart>();
    List<ImagePart> imgParts = new List<ImagePart> (headerPart.ImageParts);

    foreach(ImagePart headerImagePart in imgParts) {

         string newUri = headerImagePart.Uri.ToString();
              if(newUri != uri) {
                   list.Add(headerImagePart);
              }
         }

    headerPart.DeleteParts(list);
}
//...

1 个答案:

答案 0 :(得分:1)

图像由OpenXml中的2个部分组成;您拥有实际的图像本身,并且还有文档中显示图像的Picture容器的详细信息。

如果您考虑在同一文档中多次显示图像,这是有意义的;图像的细节可以存储一次,图像的位置可以根据需要存储多次。

以下代码将查找包含您要删除的Drawing个对象的任何ImagePart个对象。这是通过将Embed的{​​{1}}属性与Blip的ID进行匹配来完成的。

ImagePart

正如您在评论中指出的那样,您需要添加一个using语句:

using (WordprocessingDocument document = WordprocessingDocument.Open(filename, true))
{
    foreach (HeaderPart headerPart in document.MainDocumentPart.HeaderParts)
    {
        List<ImagePart> list = new List<ImagePart>();
        List<ImagePart> imgParts = new List<ImagePart>(headerPart.ImageParts);
        List<Drawing> drwdDeleteParts = new List<Drawing>();
        List<Drawing> drwParts = new List<Drawing>(headerPart.RootElement.Descendants<Drawing>());

        foreach (ImagePart headerImagePart in imgParts)
        {
            string newUri = headerImagePart.Uri.ToString();
            if (newUri != uri)
            {
                list.Add(headerImagePart);

                //you also need to find the Drawings the image was related to
                IEnumerable<Drawing> drawings = drwParts.Where(d => d.Descendants<Pic.Picture>().Any(p => p.BlipFill.Blip.Embed == headerPart.GetIdOfPart(headerImagePart)));

                foreach (var drawing in drawings)
                {
                    if (drawing != null && !drwdDeleteParts.Contains(drawing))
                        drwdDeleteParts.Add(drawing);
                }
            }
        }

        foreach (var d in drwdDeleteParts)
        {
            d.Remove();
        }

        headerPart.DeleteParts(list);
    }
}