ReportViewer Excel檔的考驗: EPPlus、NPOI與Open XML SDK
0 |
前陣子曾排除過一枚EPPlus處理ReportViewer匯出xlsx的Bug,繼續深入才發現事情遠比想像複雜: 表格式報表經ReportViewer匯出成Excel檔,透過EPPlus處理存檔後,用Excel開啟又再次爆出xl/styles.xml及xl/worksheets/sheet1.xml損壞訊息,經修復可讀取,但已原本的格式、顏色設定盡失。
圖1 ReportViewer匯出的原始Excel檔,實驗目標是將"A1"儲存格改成"已修改"
圖2 EPPlus處理後發生錯誤,樣式遺失
試著追進Source Code,發現問題埋得頗深。由於EPPlus在存檔時會重新以自己的角度詮釋及重整Open XML文件,即使我們只改一個欄位,XML也會經過一番重構;當原始內容偏複雜,就會產出不符合Excel或Open XML標準的結果。評估要修正這些問題將涉及大規模核心邏輯翻寫,工程不小,有違想利用元件簡化開發的初衷。還在Alpha階段的NPOI 2.0已能支援xlsx,決定也讓它上場試試,考驗一下能否正確處理ReportViewer的匯出檔。
圖3 NPOI存檔後也發生錯誤,遺失樣式設定
可惜,NPOI也闖關失敗,修復訊息中出現很嚇人的"災難性的失敗",且修改結果也未出現。
最後,只能考慮相形之下較難用的Open XML SDK(目前已經出到2.5,但還是只像為硬綁綁的XML套了層絨布套,坐了屁股照樣會疼),由於它基本上是用維護XML文件的角度進行操作,不會重構翻寫XML,破壞結構風險低很多。而它也是本次測試唯一修改成功且Excel開啟正常的範例。
圖4 Open XML SDK 2.5修改結果
附上程式碼供參考:
static void Main(string[] args)
{
string src = @"d:\temp\source.xlsx";
//NOPI
IWorkbook workbook = new XSSFWorkbook(src);
ISheet sheet = workbook.GetSheetAt(0);
sheet.GetRow(0).GetCell(0).SetCellValue("已修改");
FileStream sw = File.Create(@"d:\temp\npoi.xlsx");
workbook.Write(sw);
sw.Close();
//EPPlus
using (ExcelPackage p = new ExcelPackage(new FileInfo(src)))
{
var sht = p.Workbook.Worksheets.First();
sht.Cells[1, 1].Value = "已修改";
p.SaveAs(new FileInfo(@"d:\temp\epplus.xlsx"));
}
//OpenXML SDK 2.5
//REF: http://msdn.microsoft.com/en-us/library/office/cc850837.aspx
string dst = src.Replace(Path.GetFileName(src), "sdk.xlsx");
File.Copy(src, dst, true);
using (var shtDoc = SpreadsheetDocument.Open(dst, true))
{
var sht = shtDoc.WorkbookPart.Workbook.Descendants<Sheet>().First();
var shtPart = shtDoc.WorkbookPart.GetPartById(sht.Id) as WorksheetPart;
var cell = shtPart.Worksheet.Descendants<Row>().First()
.Descendants<Cell>().First();
cell.RemoveAllChildren();
//REF: InlineString http://bit.ly/ZpUf18
var ins = new InlineString();
ins.AppendChild(new Text("已修改"));
cell.AppendChild(ins);
cell.DataType =
new DocumentFormat.OpenXml.EnumValue<CellValues>(
CellValues.InlineString);
//shtPart.Worksheet.Save();
shtDoc.WorkbookPart.Workbook.Save();
shtDoc.Close();
}
}
【2012-12-28補充】新選擇: 令人驚豔的Excel程式庫 - ClosedXML
Comments
Be the first to post a comment