输出.XLSX到响应时EPPlus错误
我有一个奇怪的问题在这里使用EPPlus来创build一些.XLSX文件。 我有一个包被创build,然后被输出到响应。
我已经创build了一个包,如下所示:
var file = new FileInfo(@"C:\Test.xlsx"); ExcelPackage package = new ExcelPackage(file); //...code to output data...// package.Save();
这将文件保存到我的本地C:驱动器正确,当我打开它的效果很好。 没有错误或任何东西,格式是正确的,等等。
不过,我现在想输出这个文件到响应stream,所以我修改了代码,我看起来像这样:
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在filename.xlsx中发现不可读的内容。 你想恢复这个工作簿的内容? 如果您信任此工作簿的来源,请单击“是”
点击是,然后显示以下提示:
此文件不能通过使用Microsoft Excel打开。 您是否要searchMicrosoft Office Online网站上的可以打开文件的转换器?
我在这里selectNo
,然后打开Excel文件并显示这个错误:
Excel完成文件级别validation和修复。 此工作簿的某些部分可能已被修复或丢弃。
但文件然后加载罚款,似乎格式正确,一切。 但每次我尝试打开文件时,都会给出相同的提示和错误消息。
注意:输出数据的代码在这些情况下都不会改变。
有没有人看过像这样的东西? 或者有什么想法, 只有当输出到响应时,可能导致此错误保存文件?
我find了解决这个问题的办法! 正如预期的那样,这与响应有关,因为我可以在本地保存时打开文件,但不能通过响应。
这里的问题是,我的代码被包装在一个try..catch块,其中的exception被logging和显示。
我注意到,当你调用Response.End()时,会引发一个System.Threading.ThreadAbortExceptionexception 。 当这被提出,似乎错误的输出被追加到我的文件的末尾。
当我摆脱了特定exception的错误logging,它工作得很好!
请参阅这篇文章的更多信息http://epplus.codeplex.com/discussions/223843?ProjectName=epplus
//...output code...// catch(Exception ex){ if (!(ex is System.Threading.ThreadAbortException)) { //Log other errors here } }
感谢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
而不是WriteTo
方法,试试这个:
context.Response.BinaryWrite(package.GetAsByteArray());
button单击“导出到Excel”时,page.aspx.cs代码
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; } }
我不能从IE打开EPPlus,它保存得很好,并打开没有错误。 (铬工作正常保存和打开)。 这里的build议不适合我 – 可能是因为我使用的是aspx文件,而不是最后为我工作的ashx文件。
经过几个小时的search,我结束了根据这个stackoverflowpost使用ashx文件,我现在在所有的浏览器工作,没有使用EPPlus警告/ corupt文件消息。
可能有助于他人的额外资源:
- http://epplus.codeplex.com/discussions/223843?ProjectName=epplus
- 输出.XLSX到响应时EPPlus错误
我希望这能节省一些时间。