如何通过OpenXML从Excel工作簿中删除/删除ExtensionList?

我有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> 

通过删除整个元素或删除<ext>标记中的x: <ext>然后在打包备份后工作簿将正常工作。

我也尝试了下面的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'是每次都不明确的前缀错误。 有谁知道如何解决这一问题? 任何帮助将不胜感激。

据我所知,你不能用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文件(我感到你的痛苦…)。

+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文件中删除<extLst>节点并修复工作簿。

 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