如何使用 Open XML SDK 删除 Word 和 PowerPoint 中的所有嵌入对象?

问题描述 投票:0回答:3

我正在尝试使用 openxml SDK 从 Word 和 PowerPoint 文件中删除所有嵌入对象。我是 Open XML 新手,不确定我这样做是否正确。下面是我的代码。我的目的是删除嵌入的任何对象并删除嵌入的图像。执行时这两个代码都会出错。

我尝试删除文档中所有嵌入项目的代码。

using (var wdDoc = WordprocessingDocument.Open(wordFilePath, true))
{
    var docPart = wdDoc.MainDocumentPart;
    var document = docPart.Document;
    var embeddedObjectsCount = docPart.EmbeddedObjectParts.Count();
    while (embeddedObjectsCount > 0)
    {
        docPart.DeletePart(docPart.EmbeddedObjectParts.FirstOrDefault());
        embeddedObjectsCount = docPart.EmbeddedObjectParts.Count();
    }
}

我尝试删除文档中所有图像的代码。 (如果我没有在文档中嵌入任何对象,这会部分起作用。)

using (var wdDoc = WordprocessingDocument.Open(wordFilePath, true))
{
    var docPart = wdDoc.MainDocumentPart;
    var document = docPart.Document;
    var imageObjectsCount = docPart.ImageParts.Count();
    while (imageObjectsCount > 0)
    {
        docPart.DeletePart(docPart.ImageParts.FirstOrDefault());
        imageObjectsCount = docPart.ImageParts.Count();
    }
}

当我运行上面的代码时,我使用的文件被损坏。我想知道如何从 Word 中删除所有嵌入对象而不损坏文件。

我还没有在PowerPoint上做过任何事情,但我希望它能类似于Word文档。

c# openxml openxml-sdk
3个回答
1
投票

我设法找到解决问题的方法。我必须深入研究 Open XML SDK 的概念才能理解这一点。但是,我不太确定这是否是最佳解决方案。

目标

  1. 删除 PowerPoint 和 Word 中的所有嵌入对象。

  2. 删除 PowerPoint 和 Word 中的所有图像。

对于文字

//using Ovml = DocumentFormat.OpenXml.Vml.Office;
//Determine whether there are any Embedded Objects in the document
using (var wdDoc = WordprocessingDocument.Open(wordFilePath, true))
{
    var docPart = wdDoc.MainDocumentPart;
    var docHasEmbeddedOleObjects = document.Body.Descendants<Ovml.OleObject>().Any();
    if (docHasEmbeddedOleObjects)
    {
        foreach (var oleObj in document.Body.Descendants<Ovml.OleObject>())
        {
            oleObj.Remove(); //Remove each ole object in the document. This will remove the object from view in word.
        }
        //Delete the embedded objects. This will remove the actual attached files from the document.
        docPart.DeleteParts(docPart.EmbeddedObjectParts);
        //Delete all picture in the document
        docPart.DeleteParts(docPart.ImageParts);
    }
}

对于PowerPoint

using (var ppt = PresentationDocument.Open(powerPointFilePath, true))
{
    foreach (var slide in slides)
    {
        //Remove Ole Objects
        var oleObjectCount = slide.Slide.Descendants<OleObject>().Count();
        while (oleObjectCount > 0)
        {
            var oleObj = slide.Slide.Descendants<OleObject>().FirstOrDefault();
            var oleObjGraphicFrame = oleObj?.Ancestors<GraphicFrame>().FirstOrDefault();
            if (oleObjGraphicFrame != null)
            {
                oleObjGraphicFrame.RemoveAllChildren();
                oleObjGraphicFrame.Remove();
            }
            oleObjectCount = slide.Slide.Descendants<OleObject>().Count();
        }
        //Delete embedded objects
        slide.DeleteParts(slide.EmbeddedObjectParts);
        //Delete all pictures
        slide.DeleteParts(slide.ImageParts);
    }
}

0
投票

根据我的经验,“破坏”OpenXML 文档的最快方法是使用错误的关系指针。处理这些神秘错误消息背后的内容的最快方法是直接访问原始 OpenXML 标记。

了解正在发生的事情:

  1. 在运行代码之前复制文件,称之为
    A.docx
  2. 运行代码并复制结果,称之为
    B.docx
  3. A.docx
    B.docx
    重命名为
    A.zip
    B.zip

调查源文件

首先,在

A.zip
内部,打开名为
[Content_Types].xml
的文件。记下您要移除的部件。将此文件视为对字处理器的声明,说明它将在子目录中遇到的文件类型。

文档内容(

word/document.xml
)或脚注部分(
word/footnotes.xml
)等部分都有自己的关系部分,名为
[part path here].rels

例如,

document.xml.rels
将保存
document.xml
中的图表、超链接和图像等关系信息;同样,
footnotes.xml.rels
保存有关
footnotes.xml
中的超链接等信息。

调查结果文件

现在打开

B.zip
并比较
[Content_Types].xml
文件。您看到那里有您想要删除的部分吗?是否有遗漏的部分是您不打算删除的?

word
B.zip
子目录中,您是否看到 [Content_Types].xml 文件中
未列出的任何嵌入文件?

如果您查看原始标记,并且没有发现错误,请随时评论有关您的文件结构的更多详细信息,我们可以从那里进行故障排除。


0
投票
我已尝试使用上述代码从工作文档中删除嵌入的 ole 对象,但生成的 Word 文档已损坏且无法打开?最近有没有人尝试过 OpenXML Sdk 版本:2.20.0

© www.soinside.com 2019 - 2024. All rights reserved.