1. 程式人生 > >NPOI匯出Excel2007-xlsx格式檔案,用於web時需要注意的問題-XSSFWorkbook處理問題

NPOI匯出Excel2007-xlsx格式檔案,用於web時需要注意的問題-XSSFWorkbook處理問題

2.今天針對此問題好一頓的測試:

2.1 在有檔案構建時不是.xlsx檔案格式會報錯,構建不成。.xls檔案是不行的。

2.2 XSSFWorkbook物件呼叫 write方法傳去MemoryStream物件後,會自動關閉傳入的引數。導致往Response.OutputStream會有問題?

  HSSFWorkbook物件則不會,針對這個問題還專門查了HSSFWorkbook原始碼下面有,本來想查XSSFWorkbook的原始碼,現在還沒公開呢。

3.再有匯出.xlsx檔案時,在開啟時總報:

 錯誤提示: Excel在“春天Excel2007.xlsx”中發現不可讀取內容。是否恢復工作簿的內容?如果信任此工作簿的來源,請單擊“是”。 單擊“是”後:Excel 已完成檔案級驗證和修復。此工作簿的某些部分可能已被修復或丟棄。

那麼這些問題如何處理呢?直接上程式碼如下:
HSSFWorkbook類物件Write方法:

/// <summary>
        /// Write out this workbook to an Outputstream.  Constructs
        /// a new POI POIFSFileSystem, passes in the workbook binary representation  and
        /// Writes it out.
        /// </summary>
        /// <param name="stream">
the java OutputStream you wish to Write the XLS to</param>
public override void Write(Stream stream) { byte[] bytes = GetBytes(); POIFSFileSystem fs = new POIFSFileSystem(); // For tracking what we've written out, used if we're // going to be preserving nodes
List<string> excepts = new List<string>(1); MemoryStream newMemoryStream = new MemoryStream(bytes); // Write out the Workbook stream fs.CreateDocument(newMemoryStream, "Workbook"); // Write out our HPFS properties, if we have them WriteProperties(fs, excepts); if (preserveNodes) { // Don't Write out the old Workbook, we'll be doing our new one excepts.Add("Workbook"); // If the file had WORKBOOK instead of Workbook, we'll Write it // out correctly shortly, so don't include the old one excepts.Add("WORKBOOK"); // Copy over all the other nodes to our new poifs CopyNodes(this.filesystem, fs, excepts); } fs.WriteFileSystem(stream); fs.Dispose(); newMemoryStream.Dispose(); bytes = null; }

問題2對應程式碼:

FileStream fileStream = new FileStream(HttpContext.Current.Server.MapPath("~/Resources/Template/" + strHeaderText  + ".xlsx"), FileMode.Create, FileAccess.Write);

                workbook.Write(fileStream);//呼叫這個後會關於檔案流,在HSSFWorkbook不會關閉所以在處理時應注意
                FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("~/Resources/Template/" + strHeaderText + ".xlsx"), FileMode.Open, FileAccess.Read);
                long fileSize = fs.Length;
byte[] fileBuffer = new byte[fileSize];

                fs.Read(fileBuffer, 0, (int)fileSize);
                HttpContext.Current.Response.BinaryWrite(fileBuffer);

                fs.Close();

問題3對應程式碼:

FileStream fileStream = new FileStream(HttpContext.Current.Server.MapPath("~/Resources/Template/" + strHeaderText  + ".xlsx"), FileMode.Create, FileAccess.Write);

                workbook.Write(fileStream);//呼叫這個後會關於檔案流,在HSSFWorkbook不會關閉所以在處理時應注意               
                FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("~/Resources/Template/" + strHeaderText + ".xlsx"), FileMode.Open, FileAccess.Read);
                long fileSize = fs.Length;

           //加上設定大小下載下來的.xlsx檔案開啟時才沒有錯誤
                HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());

            byte[] fileBuffer = new byte[fileSize];
                fs.Read(fileBuffer, 0, (int)fileSize);
                HttpContext.Current.Response.BinaryWrite(fileBuffer);

                fs.Close();