c# - 使用 OpenXML SDK 删除 header 中的图像

标签 c# openxml openxml-sdk

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

当我之后打开 word 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);
}
//...

最佳答案

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

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

以下代码将查找包含您要删除的 ImagePart 对象的所有 Drawing 对象。这是通过将 BlipEmbed 属性与 ImagePart 的 Id 进行匹配来完成的。

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

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

Pic = DocumentFormat.OpenXml.Drawing.Pictures;

关于c# - 使用 OpenXML SDK 删除 header 中的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43320452/

相关文章:

c# - 连接调试器 - 当前不会命中断点。该文档尚未加载任何符号

ms-word - 在 Blazor 中创建并下载 Word 文件

openxml - 打开XML : Word Create a new Document and add a paragraph from another document

c# - 如何使用 OpenXML Sdk 替换段落的文本

javascript - 固定 Gridview 元素模板列宽和使用链接按钮查看详细信息

c# - 在 C# 应用程序中播放 Raspberry Pi h264 流

c# - 不使用 GetMethods 获取泛型方法

.net - 在不使用 Office Automation 的情况下生成 PowerPoint 演示文稿的一些技术有哪些?

ado.net - 如何使用 ADO.NET 读取 .XLSX (Excel 2007) 文件?我发现 "Could not find installable ISAM"-错误

c# - 以编程方式将字体系列嵌入 .docx 文件