2012-07-18 69 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文件消息。

其他资源,可以帮助别人:

我希望这救别人一些时间。

相关问题