2017-06-22 102 views
0

我用這段代碼寫入了一個令人興奮的excel文件。寫入文件後,當我手動打開文件時,它已損壞。我正在使用NPOI二進制文件2.3.0.0請告訴如何避免excel被損壞。NPOI - 保存到文件損壞後.xlsx工作簿

[Authorize] 
public void ExportUsers() 
{ 
    var path = Server.MapPath(@"~\Content\ExportTemplates\") + "sample.xlsx"; 

    FileStream sw = new FileStream(path, FileMode.Open, FileAccess.Read); 

    IWorkbook workbook = WorkbookFactory.Create(sw);  

    ISheet sheet = workbook.GetSheetAt(0); 
    IRow row = sheet.GetRow(12); 

    ICell cell = row.CreateCell(row.LastCellNum); 
    cell.SetCellValue("test"); 
    workbook.CreateSheet("Ripon");    
    sw.Close(); 

    using (var exportData = new MemoryStream()) 
    { 
     workbook.Write(exportData); 
     string saveAsFileName = string.Format("Export-{0:d}.xls", DateTime.Now).Replace("/", "-"); 
     System.Web.HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"; 
     System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", saveAsFileName)); 
     System.Web.HttpContext.Current.Response.Clear(); 
     System.Web.HttpContext.Current.Response.BinaryWrite(exportData.GetBuffer()); 
     System.Web.HttpContext.Current.Response.End();      
    } 
} 

新文件已創建但已損壞。我見過有人說這是固定在2.0.6版本,但仍然不適合我

回答

0

有幾個問題在這裏進行。

首先,您將從.xlsx文件開始,但將下載文件擴展名更改爲.xls.xls.xlsx不是相同的文件格式;前者是二進制格式,後者是壓縮XML格式。如果用錯誤的擴展名保存該文件,則Excel將在打開文件時報告該文件已損壞。

其次,您使用錯誤的方法從MemoryStream獲取數據。 GetBuffer將返回整個分配的內部緩衝區數組,如果緩衝區未完全滿,該數組將包括超出數據末尾的所有未使用字節。額外的空字節將導致下載的文件被損壞。如果你想獲得緩衝區中的數據,那麼你應該使用ToArray。第三,看起來您使用的是ASP.NET MVC框架(基於您的方法中存在[Authorize]屬性),但您直接操縱當前響應,而不是使用控制器的內置File方法返回一個可下載的文件。我會建議儘可能使用內置方法,因爲它會使代碼更清潔。

這裏是校正後的代碼:

[Authorize] 
public ActionResult ExportUsers() 
{ 
    var path = Server.MapPath(@"~\Content\ExportTemplates\") + "sample.xlsx"; 

    FileStream sw = new FileStream(path, FileMode.Open, FileAccess.Read); 

    IWorkbook workbook = WorkbookFactory.Create(sw); 

    ISheet sheet = workbook.GetSheetAt(0); 
    IRow row = sheet.GetRow(12); 

    ICell cell = row.CreateCell(row.LastCellNum); 
    cell.SetCellValue("test"); 
    workbook.CreateSheet("Ripon"); 
    sw.Close(); 

    var exportData = new MemoryStream(); 
    workbook.Write(exportData); 
    exportData.Seek(0, SeekOrigin.Begin); // reset stream to beginning so it can be read 

    string saveAsFileName = string.Format("Export-{0:d}.xlsx", DateTime.Now).Replace("/", "-"); 

    return File(exportData, "application/vnd.ms-excel", saveAsFileName); 
}