In my project there is a specific page that exports a lot of data (around 1 million rows and 30 columns) in an excel "XLSX" file. But the file size is big, so it is taking a lot to download the file. However when I manually saved the file as "XLSB" (binary format) then it significantly reduced the file size.
The coding part to create and download xlsx file is working fine. I am using the following code to do this:
DataTable dtDump = GetData();
workSheet_dump.Cells["A1"].LoadFromDataTable(dtDump, true);
using (var memoryStream = new MemoryStream())
{
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=DumpReport.xlsx");
excel.SaveAs(memoryStream);
memoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
Is there any way in epplus, or any alternative way by which I can export the data in "XLSB" format?
Related
I am able to to generate excel file from asp:table,but after generating excel file while opening file it gives warning .file you are trying to open is in a different format than specified by the file extension I have found solution to this warning from this link http://www.aspsnippets.com/Articles/Solution-ASPNet-GridView-Export-to-Excel-The-file-you-are-trying-to-open-is-in-a-different-format-than-specified-by-the-file-extension.aspx
so i have used ClosedXML Library but while adding data to excel sheet it's accepting datable,dataset format only and i got data in string format so it's generating blank excel sheet. please check code i have tried.
LoadDetailsToTable();
System.IO.StringWriter sw = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter hw = new HtmlTextWriter(sw);
tbl_loctbl.RenderControl(hw);
using (XLWorkbook wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("asd");
ws.Cell(2, 1).InsertTable(sw.ToString());
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("content-disposition", String.Format(#"attachment;filename=newfile.xlsx"));
using (MemoryStream MyMemoryStream = new MemoryStream())
{
wb.SaveAs(MyMemoryStream);
MyMemoryStream.WriteTo(HttpContext.Current.Response.OutputStream);
MyMemoryStream.Close();
}
HttpContext.Current.Response.End();
}
Here LoadDetailsToTable() function load data to asp table.tbl_loctbl is table id.
Unfortunately the two markups you're using are incompatible. HTML table markup in Excel is supported, but its not in OpenXML which is what your library is expecting to output.
Under the hood, Excel is expecting a valid XML file format; html, while loosely supported, isn't the native xlsx format.
There are libraries available that will convert html to openxml on the internet, however this can be solved by iterating over your dataset and actually adding cells and rows using the OpenXML SDK
i am generating Excel report using string writer.i generated the excel sheet but it generats only one sheet.but i need to create sheets based on my condition.
my code is:
string filename = "DownloadMobileNoExcel.xls";
System.IO.StringWriter tw = new System.IO.StringWriter();
tw.Write("<table>");
tw.Write("<tr><td>data1</td><td>data2</td><td>data3</td><td>data4</td><td>data5</td><td>data6</td></tr>");
tw.Write("<tr><td>data1</td><td>data2</td><td>data3</td><td>data4</td><td>data5</td><td>data6</td></tr>");
tw.Write("<tr><td>data1</td><td>data2</td><td>data3</td><td>data4</td><td>data5</td><td>data6</td></tr>");
tw.Write("</table>");
Response.ContentType = "application/vnd.ms-excel";
Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename + "");
this.EnableViewState = false;
Response.Write(tw.ToString());
Response.End();
The above Code generate single sheet but i want to create based on my condtion,how can i create sheets,i want same method which would to append the Html ,advance Thanks
it can be done using frames: you'll have to create one .html file for each tab you want in the Excel sheet.
To see how it works,
- create an Excel file with 2 sheets
- Save As... .html
- look at the html written (+ the subfolder generated containing the sheets
If you create a similar structure (using the files from the above test as templates), Excel will be able to open it.
Another approach is to create an Excel file using OpenXml, as decribed here:
How to write data on new sheet of EXCEL
I have this code to extract a table to computer in a .xls file:
// I have a string which contains HTML table codes, named as excelTable
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.AddHeader("Content-Disposition", String.Format("Attachment;Filename=file.xls", ));
response.Buffer = true;
response.ContentEncoding = System.Text.Encoding.Default;
response.ContentType = "application/vnd.ms-excel";
response.Write(excelTable);
response.End();
And I have seen that this is not a real .xls file. I can open it in Notepad and see my standart html table codes.
Now I understand that defining ContentType is not enough. So what else can I do to generate a pure .xls or .xlsx file? Or Should I certainly use Excel Libraries like OpenXML, Interop, etc. ?
Actual XLS/XLSX data must be sent back - that is, data generated with a library (e.g EEPlus) or other suitable source.
This common hack/approach works because Excel "knows how to read HTML". It doesn't actually turn the HTML into XSL/XLSX, although it can be saved as new spreadsheet once loaded by Excel.
Changing the content type will have no effect on the data, and instead will effectively stop this approach from working: the content type is used for associating the program (i.e. Excel) which will be used to open/read the data.
So yes: to generate a real XLS/XLSX document, use a library.
I am using the EPPlus library to create an .xlsx file which I am then streaming to the browser. To stream the code I am using:
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + Server.MapPath("xls/"+ download_results_filename));
HttpContext.Current.Response.TransmitFile(Server.MapPath("xls/" + download_results_filename));
HttpContext.Current.Response.Flush();
My question is this. If I use my code along with the library, save and open the document everything is fine. However, when I create the file on the server and stream it to the user, using the code above, I get a corrupt file message with the additional ability to correct or recover the file, which I do and the file displays correct; so if using the octet stream method above to stream the file to the user corrupts the file how should I stream the Binary data to the user. I want to keep the content type to 'application/octet-stream' as if I am specific about it being an excel spreadsheet I run into problems on the iPad.
Thanks
Did you see this example?
http://epplus.codeplex.com/wikipage?title=WebapplicationExample
It use this line
Response.BinaryWrite(pck.GetAsByteArray());
I have an ASP.NET page where a user provides an ID, and then we pull some data from the DB and put it into an Excel spreadsheet. I would like to create the Excel file in memory and then allow the user to download the file. I could create a file on the server, and then delete it afterwards, but it seems unnecessary. Depending on error handling I could potentially orphan a file with that approach, etc.
Is something like this possible? Or do I need to use a file stream?
On a side note, I'm using EPPlus as an API (quick plug for it).
You want to specify the content-type and content-dispisition headers like so - Response.ContentType = "application/vnd.ms-excel" works in IE and firefox but not in Safari, then stream your file. Once complete, call Response.End() to stop the application execution
Code Sample:
void StreamExcelFile(byte[] bytes)
{
Response.Clear();
Response.ContentType = "application/force-download";
Response.AddHeader("content-disposition", "attachment; filename=name_you_file.xls");
Response.BinaryWrite(bytes);
Response.End();
}
ExcelPackage pck = new ExcelPackage();
.....
.....
.....
byte[] bfr = pck.GetAsByteArray();
Response.ContentType = "application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("content-disposition", "attachment; filename=ExcelFileName.xlsx");
Response.OutputStream.Write(bfr, 0, bfr.Length);
Response.Flush();
Response.Close();
Yes, look into using an HTTP Handler to stream the file to the browser from memory.
http://msdn.microsoft.com/en-us/library/ms972953.aspx
What you're looking for is called a generic handler:
http://www.dotnetperls.com/ashx
In a nutshell, what you need to do is define the context type. Which in your case will be a xls or xlsx. Set the response, and direct the user to the handler.
They will be prompted to download the file.