2012-07-18 70 views
14

我在這裏使用EPPlus創建一些.XLSX文件時出現了一個奇怪的問題。我有一個包被創建,然後被輸出到響應。將.XLSX輸出爲響應時出現EPPlus錯誤

var file = new FileInfo(@"C:\Test.xlsx"); 
ExcelPackage package = new ExcelPackage(file); 
//...code to output data...// 
package.Save(); 

這個文件保存到我的本地C:正確地驅動,當我打開它,它的偉大工程

我有如下創建一個包。沒有錯誤或任何東西,格式是否正確等

不過,我現在想的輸出文件的響應流,所以我已經修改了代碼,我只好這個樣子:

ExcelPackage package = new ExcelPackage(); 
//...code to output data...// 
MemoryStream result = new MemoryStream(); 
package.SaveAs(result); 
context.Response.Clear(); 
context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";              
context.Response.AddHeader("Content-Disposition", "attachment;filename=MissionDetails.xlsx"); 
result.WriteTo(context.Response.OutputStream); 
context.Response.End(); 

但是當我運行此代碼,我在嘗試打開Excel文件時出現以下提示:

Excel found unreadable content in filename.xlsx. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes

單擊是顯示以下提示:

This file cannot be opened by using Microsoft Excel. Do you want to search the Microsoft Office Online Web site for a converter that can open the file?

我選擇No這裏,然後打開Excel文件並顯示此錯誤:

Excel completed file level validation and repair. Some parts of this workbook may have been repaired or discarded.

文件然後加載罰款,似乎是正確的,一切都格式化。但是,每次我嘗試打開文件時,它都會提供相同的提示和錯誤消息。

Note: The code to output the data does not change for either of these scenarios.

有沒有人看過類似的東西?或者有什麼想法什麼可能導致此錯誤地保存文件只有當輸出到響應?

+0

爲了測試的目的,您可以簡化文件的內容(即設置單個單元格的值),以確保文件內容與文件流相比沒有問題? – JustinStolle 2012-07-18 21:22:52

+0

就像上面說的,內容和我將它保存到硬盤時相同。我已經測試了這一點並驗證了它不是我添加到單元格中的內容。響應必須是一些問題。 – j00b 2012-07-18 21:43:50

+0

因此,創建一個非常簡單的文件流來驗證問題出在哪裏 - 如果是這樣的話,它可能與EPPlus沒有任何關係。 – JustinStolle 2012-07-18 21:47:56

回答

0

取而代之的是WriteTo方法,試試這個:

context.Response.BinaryWrite(package.GetAsByteArray()); 
+1

我嘗試過,發現它在嘗試打開文件時出現以下錯誤:「Excel無法打開文件'(文件名)'.xlsx',因爲文件格式或文件擴展名無效。請確認文件沒有已被破壞,文件擴展名與文件格式相匹配。「 – j00b 2012-07-18 20:29:05

+0

你使用的是什麼版本的Office/Excel?您可能需要升級或使用兼容包(請參閱http://www.microsoft.com/zh-cn/download/details.aspx?id=3)。 – JustinStolle 2012-07-18 20:38:32

+0

我相信您需要Excel 2007或更高版本來閱讀EPPlus軟件包創建的較新的Open Office XML兼容格式。 – JustinStolle 2012-07-18 20:46:39

13

我已經找到了解決這個問題!正如預期的那樣,它確實與響應有關,因爲我可以在本地保存時打開文件,但不能通過響應。

這裏的問題是,我的代碼被封裝在一個try..catch塊中,其中異常被記錄和顯示。

它來到了我的注意,當你調用到Response.End()一個System.Threading.ThreadAbortException提高。當這種情況發生時,似乎錯誤的輸出被追加到我的文件的末尾。

當我擺脫了特定異常的錯誤日誌記錄,它工作得很好!

請參閱這篇文章獲取更多信息http://epplus.codeplex.com/discussions/223843?ProjectName=epplus

//...output code...// 
catch(Exception ex){ 
    if (!(ex is System.Threading.ThreadAbortException)) 
    { 
     //Log other errors here 
    } 
} 
+1

在Response.Flush()上引發異常。我刪除該方法,然後文件打開罰款沒有任何錯誤。 – user1131926 2012-10-07 11:34:24

0

page.aspx。CS代碼時,按鈕點擊導出到Excel

string templateFileName = Server.MapPath("~/ReportingTemplate/test.xlsx"); 
       System.IO.FileInfo templateFile = new System.IO.FileInfo(templateFileName); 

       String message = ExcelPackagePlusLibrary.EPPlus.ExportToExcel(templateFile, dt, false, exportFileName, Response, "Data", "Summary", "Please type the client name here"); 
       if (String.IsNullOrEmpty(message) == false) 
       { 
        /* Exception occur. */ 
       } 
       dt.Clear(); 
/////////////////////////////////////////////////////////////////////////////////////// 

    /// <summary> 
      /// ExportToExcel is a method used for Export To Excel with template file. 
      /// 
      /// </summary> 
      /// <param name="templateFile">The fully qualified name of the new file, or the relative file name. Do not end the path with the directory separator character.</param> 
      /// <param name="dt">Datatable for export.</param> 
      /// <param name="printHeaders">Datatable's header used or not, when Export it. </param> 
      /// <param name="exportFileName">provide fileName only not path. </param> 
      /// <param name="Response">System.Web.HttpResponse. </param> 
      /// <param name="sheetNames">arg[0] means provide sheet name where you want to load data. \n (Optional Parameter) arg[1] means provide sheet name where you want to edit. (Optional Parameter) arg[2] means if your intention is to Edit sheet so provide searchText.</param> 
      /// 
      public static string ExportToExcel(FileInfo templateFile, DataTable dt, bool printHeaders, string exportFileName, System.Web.HttpResponse Response, params String[] sheetNames) 
      { 
       try 
       { 
        using (ExcelPackage p = new ExcelPackage(templateFile, false)) 
        { 
         EPPlus.AddSheetWithTemplate(p, dt, sheetNames[0], printHeaders); 


         String[] clientName = exportFileName.Split(new char[] { '_' }, 2); 

         if (sheetNames.Count() > 2) 
         { 
          ExcelPackagePlusLibrary.EPPlus.EditSheet(p, sheetNames[1], sheetNames[2], clientName[0] ?? exportFileName); 
         } 

         Byte[] fileBytes = p.GetAsByteArray(); //Read the Excel file in a byte array 

         //Clear the response 
         Response.ClearHeaders(); 
         Response.ClearContent(); 
         Response.Clear(); 

         //Response.Cookies.Clear(); 


         //Add the header & other information 
         //Response.Cache.SetCacheability(System.Web.HttpCacheability.Private); 
         //Response.CacheControl = "private"; 
         //Response.Charset = System.Text.UTF8Encoding.UTF8.WebName; 
         //Response.ContentEncoding = System.Text.UTF8Encoding.UTF8; 
         //Response.AppendHeader("Content-Length", fileBytes.Length.ToString()); 
         //Response.AppendHeader("Pragma", "cache"); 
         //Response.AppendHeader("Expires", "60"); 
         Response.AddHeader("Content-Disposition", 
         "attachment; " + 
         "filename=" + exportFileName + "; " + 
         "size=" + fileBytes.Length.ToString() + "; " + 
         "creation-date=" + DateTime.Now.ToString("R").Replace(",", "") + "; " + 
         "modification-date=" + DateTime.Now.ToString("R").Replace(",", "") + "; " + 
         "read-date=" + DateTime.Now.ToString("R").Replace(",", "")); 

         //Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 
         Response.ContentType = "application/x-msexcel"; 

         //Write it back to the client 
         Response.BinaryWrite(fileBytes); 
         Response.Flush(); 
         Response.Close(); 

         /* Download to Client Side. */ 
         //DirectoryInfo dir = new DirectoryInfo(Server.MapPath("~/Testing/Downloaded/" + DateTime.Now.ToString("MM-dd-yyyy"))); 
         //if (!dir.Exists) 
         //{ 
         // dir.Create(); 
         //} 
         //File.WriteAllBytes(dir.FullName + "\\" + fileName, fileBytes); 

         return String.Empty; 
        } 
       } 
       catch (Exception ex) 
       { 
        _ErrorMessage = ex.Message.ToString(); 
        return _ErrorMessage; 
       } 
      } 
8

感謝您JOOB鏈接soved我的問題,它在呼喚 「GetAsByteArray()」。如下所示,並在你給的鏈接,我gess保持例外被追加。由一些majic。

您獲得並投票!

mrxrsd 
Editor 

Aug 17, 2010 at 12:30 PM 


Call response.clear before send stream back to client. 

        Response.Clear(); 
        Response.AddHeader("content-disposition", "attachment; filename=file.xlsx"); 
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";     
        Response.BinaryWrite(pck.GetAsByteArray()); 
        Response.End(); 

http://epplus.codeplex.com/discussions/223843?ProjectName=epplus

0

我不能讓EPPlus從IE中打開,它保存的很好,沒有錯誤打開。 (鉻在保存和打開方面都工作得很好)。這裏的建議對我不起作用 - 可能是因爲我使用的是aspx文件,而不是最後爲我工作的ashx文件。

經過幾個小時的搜索,我結束了根據this stackoverflow post使用ashx文件,並且現在它可以在所有瀏覽器中使用,而不使用EPPlus發出警告/ corupt文件消息。

其他資源,可以幫助別人:

我希望這救別人一些時間。

相關問題