發現EPPlus 3.1.2版Bug一枚。

開啟現有xlsx後,不做任何修改就儲存,再使用Excel開啟會出錯。例如以下範例:

using (ExcelPackage p = new ExcelPackage(new FileInfo("通訊錄.xlsx")))

    p.Save();
}

程式執行後使用Excel開啟重新儲存的通訊錄.xlsx檔案,會出現以下錯誤:

Excel 在 '通訊錄.xlsx' 中找到無法讀取的內容。您要回復此活頁簿的內容嗎? 若您信任此活頁簿的來源,請按一下[是]。
Excel found unreadable content in filename.xls. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes.

試圖修復,Excel會回報進一步訊息。

檢視錯誤訊息xml檔,會發現關於style.xml及sheet*.xml的修復報告:

error067160_07.xml檔案 'X:\TestEPPlus\bin\Debug\通訊錄.xlsx' 中偵測出錯誤
已移除的記錄: /xl/styles.xml 部分的 樣式 (樣式)
已修復的記錄: /xl/worksheets/sheet1.xml 部分的 儲存格資訊
已修復的記錄: /xl/worksheets/sheet1.xml 部分的 欄資訊

修復後的xlsx檔案,資料完好,但格式設定大亂。

幸好,xlsx檔的本質是個ZIP壓縮檔,解開後就可以進一步探查真相。在xl\styles.xml檔案中,我發現幾處不合理的XmlNode:

<cellStyleXfs count="2">
  <xf numFmtId="0" fontId="0" fillId="0" borderId="0">
    <alignment vertical="center" />
  </xf>
</cellStyleXfs>
<cellXfs count="3">
  <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="1">
    <alignment vertical="center" />
  </xf>
  <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="1">
    <alignment vertical="center" />
  </xf>
</cellXfs>
<cellStyles count="2">
  <cellStyle name="一般" xfId="1" builtinId="0" />
</cellStyles>

cellStyleXfs count=2,但資料只有一筆、cellXfs count=3,但資料只有兩筆,而且xfId都是"1",cellStyles count=2但資料只有一筆。推測就是這些錯亂導致styles.xml出錯,而sheet1.xml與sheet2.xml的對應也因此損壞,造成格式顯示異常。

感謝老天爺,EPPlus是個Open Source Project,下載原始碼用Line-By-Line追進元件內部,沒多久就找到Bug來源:

EPPlus\ExcelStyles.cs Line 562 UpdateXml() method:

Line 561:            //NamedStyles
Line 562:            count = 1; <== 應改成count = 0;才合理

經過修改,原本存檔會弄壞xlsx檔的問題消失了! 順便把我的發現回報到CodePlex,終於有機會為Open Source社群略盡薄棉之力,Open Source萬歲!


Comments

# by C#初学者

你好,我现在用Epplus 4.5.3.3 不做任何修改,保存xlsx打开同样也是出现跟你一样的问题,是不是官方没有对这个进行修复

Post a comment