【问题标题】:How to remove/delete the ExtensionList from an Excel workbook via OpenXML?如何通过 OpenXML 从 Excel 工作簿中删除/删除 ExtensionList?
【发布时间】:2013-07-15 19:50:52
【问题描述】:

我有 100 多个工作簿已损坏 - 当试图打开它们时,Excel 会抛出一条错误消息,指出“x”是一个未声明的前缀。这些文件无法在 xml 查看器(包括 OpenXML 之一)中加载。现在,如果我将 Excel 工作簿的扩展名更改为 .zip,解压缩所有部分,在 workbook.xml 文件中编辑以下行(这是 xml 文档中的最后一个元素)

<extLst><x:ext uri="{140A7094-0E35-4892-8432-C4D2E57EDEB5}" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"><x15:workbookPr chartTrackingRefBase="1"/></x:ext></extLst>

通过删除整个元素或删除&lt;ext&gt; 标记中的x:,我将其打包备份后工作簿将正常运行。

我也试过下面的 VB.Net 代码:

 Private Sub RemoveExceptionsFromWorkbook(ByVal workbookPath As String)
        Using excelDoc As SpreadsheetDocument = SpreadsheetDocument.Open(workbookPath, True)
            If excelDoc.WorkbookPart.Workbook.Descendants(Of WorkbookExtensionList)().Any() Then
                excelDoc.WorkbookPart.Workbook.RemoveAllChildren(Of WorkbookExtensionList)()
                excelDoc.WorkbookPart.Workbook.Save()
            End If
        End Using
    End Sub

但我每次都得到“x”是一个未声明的前缀错误。有谁知道如何解决这一问题?任何帮助将不胜感激。

【问题讨论】:

    标签: .net xml vb.net excel openxml


    【解决方案1】:

    据我所知,您无法使用 Excel 或 Open XML SDK 执行此操作,因为文件本身已损坏。这意味着您必须像修改普通的 ZIP 文件一样对其进行修改。为了方便起见,我使用了 DotNetZip,但您可以使用任何您喜欢的 ZIP 库。试试这个:

    using (ZipFile zf = ZipFile.Read("damagedcopy.xlsx"))
    {
        ZipEntry ze = zf["xl/workbook.xml"];
        using (MemoryStream ms = new MemoryStream())
        {
            ze.Extract(ms);
            // this is important, otherwise the StreamReader starts from the end.
            ms.Position = 0;
            StreamReader sr = new StreamReader(ms);
            string streamdata = sr.ReadToEnd();
            // I only updated the relevant portion of the XML
            streamdata = streamdata.Replace("<x:ext", "<ext");
            streamdata = streamdata.Replace("</x:ext>", "</ext>");
            sr.Close();
            zf.UpdateEntry("xl/workbook.xml", streamdata);
            zf.Save();
        }
    }
    

    根据需要遍历所有 100 多个 Excel 文件(我感到很痛苦……)。

    【讨论】:

      【解决方案2】:

      +1 给 Vincent Tan 的概念。你是对的 - xml 文件无法打开,所以我必须先将其修改为文本文件。首先我在上面运行了这个:

      Private Sub RemovePrefix()
           'Change the extension of the workbook.xml file to txt
           IO.File.Move(WorkbookXmlFilePath, WorkbookXmlTxtFileName)  
      
           Dim arrText() As String = IO.File.ReadAllLines(WorkbookXmlTxtFileName)
           Dim arrNewText(arrText.Length - 1) As String
      
           For i As Integer = 0 To UBound(arrText)
                If arrText(i).Contains("x:") Then
                     arrNewText(i) = Strings.Replace(arrText(i), "x:", "")
                Else
                     arrNewText(i) = arrText(i)
                End If
           Next
      
           IO.File.WriteAllLines(WorkbookXmlTxtFileName, arrNewText)
      
           'Change the extension back to xml
           IO.File.Move(WorkbookXmlTxtFileName, WorkbookXmlFilePath)
      End Sub
      

      之后,xml 文件不再损坏,但尝试打开 Excel 工作簿仍然给我一条消息,指出数据已损坏。因此,我的问题中的过程随后可以从 workbook.xml 文档中完全删除 &lt;extLst&gt; 节点并修复工作簿。

      Private Sub RemoveExceptionList(ByVal workbookPath as String)
           Using excelDoc As SpreadsheetDocument = SpreadsheetDocument.Open(workbookPath, True)
                If excelDoc.WorkbookPart.Workbook.Descendants(Of WorkbookExtensionList)().Any() Then
                     excelDoc.WorkbookPart.Workbook.RemoveAllChildren(Of WorkbookExtensionList)()
                     excelDoc.WorkbookPart.Workbook.Save()
                End If
           End Using
       End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-03
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多