2016-12-01 142 views
1

在ASP.Net中,我使用NPOI將保存寫入Excel文檔,並且我剛剛移動到版本2+。它很好地寫入xls,但切換到xlsx更具挑戰性。我的新改進的代碼是將大量的NUL字符添加到輸出文件。將它寫入Response.OutputStream時得到一個損壞的XLSX文件

結果是,Excel抱怨說有「內容有問題」,我希望他們嘗試恢復嗎?

下面是從我的十六進制編輯器創建的xlsx文件的圖片: BadXlsxHexImage這些00s繼續打印幾頁。我從字面上刪除了編輯器中的那些內容,直到文件打開時沒有錯誤。

這段代碼爲什麼會在這個文件中添加如此多的NUL?

using (var exportData = new MemoryStream()) 
{ 
    workbook.Write(exportData); 
    byte[] buf = exportData.GetBuffer(); 

    string saveAsFileName = sFileName + ".xlsx"; 

    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 
    Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}; size={1}", saveAsFileName, buf.Length.ToString())); 
    Response.Clear(); 
    Response.OutputStream.Write(buf, 0, buf.Length); 
    exportData.Close(); 
    Response.BufferOutput = true; 
    Response.Flush(); 
    Response.Close(); 
} 

(我已經到位的OutputStream.WriteResponse.End試圖BinaryWrite代替Response.Close,並與緩衝區的長度設置Content-Length。另外,這一切都不是寫入XLS的問題。)

+0

如果你想使用其他lib下,這裏是最好的之一,我認爲創建XLSX:https://epplus.codeplex.com/ – andrefadila

回答

1

你得到一堆空字節的原因是因爲你在MemoryStream上使用GetBuffer。這將返回整個已分配的內部緩衝區數組,如果緩衝區未完全滿,將包含超出數據末尾的未使用字節。如果你想獲得緩衝區中的數據(你肯定會這樣做),那麼你應該使用ToArray來代替。

這就是說,你爲什麼要寫一個MemoryStream?您已有一個要寫入的流:OutputStream。只需將工作簿直接寫入即可。

試試這樣說:

Response.Clear(); 
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", saveAsFileName)); 
workbook.Write(Response.OutputStream); 
Response.Flush(); 
Response.Close(); 
+0

約尼斯抓使用'OutputStream'。這一改變徹底清除了它!我期望'GetBuffer'能夠處理修剪,但知道它實際上獲得了緩衝區而不是在幕後幫助。 –

+0

此代碼在download.aspx中的Page_Load事件中調用。 Firefox和IE處理它很好,但Chrome繼續處理頁面中的HTML並將其附加到緩衝區。 是否應該修改此代碼以解釋這一點?可能結束'OutputStream'? (我嘗試'OutputStream.End()',但它沒有幫助。) –