C# Aspx Web 匯出Excel2007-xlsx格式檔案用NPOI外掛的問題

TA遠方發表於2019-07-24

文件檔案用NPOI外掛, 在有匯出.xlsx檔案時,在開啟時總報:

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

處理Excel2007、2010檔案,格式.xlsx檔案存在一個問題,在呼叫 Write方法之後關閉了傳入的檔案流

//檔案流傳入記憶體
var ms = MemoryStream();
//ms.Length;//會丟擲不可讀異常
var fileSize = file.ToArray().Length;//改用複製程式碼

問題如何處理呢?直接上程式碼如下:

由於 使用MemoryStream 這個有問題,先改用 FileStream

public void CreateExcelV2(List<work_order> list, Dictionary<string, string> cols, string FileType, string FileName)
        {
            string path = MapPath("~/Files");
            if (Directory.Exists(path) == false) Directory.CreateDirectory(path);
            string savePath = path + "/" + FileName + ".xlsx";

            try
            {
                var workbook = new XSSFWorkbook();//2007版本 xlsx
                //var workbook = new HSSFWorkbook();
                #region 建立生成表格檔案.xlsx
                var sheet = workbook.CreateSheet("Sheet1");
                //key 鍵 自定義寬度
                var regNum = new Regex(@"\d+");
                //寫入列名
                var row = sheet.CreateRow(0);
                int i = 0;
                foreach (var col in cols.Values)
                {
                    row.CreateCell(i++).SetCellValue(col);
                }
                //寫入資料
                i = 0;
                foreach (var item in list)
                {
                    row = sheet.CreateRow(i + 1);
                    int j = 0;
                    foreach (var key in cols.Keys)
                    {
                        row.CreateCell(j++).SetCellValue(getModelKeyValue(key, item));
                    }
                    i++;
                }
                #endregion
                #region 寫出表格檔案,下載
                Response.Clear();
                Response.Charset = "UTF-8";
                Response.ContentEncoding = Encoding.GetEncoding("UTF-8");
                Response.Buffer = true;
                Response.ContentType = FileType;
                //呼叫這個後會關於檔案流,在HSSFWorkbook不會關閉所以在處理時應注意 
                using (var fs = new FileStream(savePath, FileMode.Create, FileAccess.Write))
                {
                    workbook.Write(fs);
                    fs.Close();
                }
                using (var fs = new FileStream(savePath, FileMode.Open, FileAccess.Read))
                {
                    long fileSize = fs.Length;
                    byte[] fileBuffer = new byte[fileSize];
                    fs.Read(fileBuffer, 0, (int)fileSize);
                    
                    Response.AddHeader("Content-Length", fileSize.ToString());
                    Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}.xlsx\"", HttpUtility.UrlEncode(FileName, Encoding.UTF8)));

                    Response.BinaryWrite(fileBuffer);

                    Context.ApplicationInstance.CompleteRequest();
                    Response.Output.Flush();

                    fs.Close();
                }
                /*
                using (var file = new MemoryStream())
                {
                    workbook.Write(file);

                    //加上設定大小下載下來的.xlsx檔案開啟時才不會報“Excel 已完成檔案級驗證和修復。此工作簿的某些部分可能已被修復或丟棄”
                    Response.AddHeader("Content-Length", (file.ToArray().Length).ToString());
                    Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}.xlsx\"", HttpUtility.UrlEncode(FileName, Encoding.UTF8)));
                    Response.BinaryWrite(file.GetBuffer());
                    Context.ApplicationInstance.CompleteRequest();
                    Response.Output.Flush();
                    //Response.Flush();

                    file.Flush();
                    file.Close();
                }
                */
                #endregion
            }
            catch (Exception ex)
            {
                Response.Write("400, file download excetion. "+ex.Message);
            }
            finally
            {
                if (File.Exists(savePath))
                {
                    File.Delete(savePath);
                }
                Response.End();//不可以放在try 內,會丟擲異常
            }
        }
複製程式碼


參考來源:

https://www.cnblogs.com/kaiwanlin/p/5782834.html


相關文章