2013-07-15 88 views
1

我有100多個工作簿已被破壞 - 當他們試圖打開時,Excel會拋出一個錯誤消息,說'x'是一個未聲明的前綴。這些文件無法在xml查看器中加載(包括OpenXML之一)。現在,如果我改變了Excel工作簿的擴展爲.zip,解壓所有的部件,編輯下面一行通過刪除(這是XML文檔中的最後一個元素)在workbook.xml文件如何通過OpenXML從Excel工作簿中刪除/刪除ExtensionList?

<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:,然後在將其打包備份後工作簿將正常運行。

我也試過以下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」是一個未聲明的前綴錯誤。有誰知道如何解決這一問題?任何幫助將不勝感激。

回答

1

+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 
3

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

相關問題