I usually use Response.Write to export my reports to an excel file.
E.g
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=MyFile.xls");
Response.ContentType = "application/vnd.ms-excel";
Response.Write("<meta http-equiv=Content-Type content=text/html;charset=UTF-8>");
Response.Write("<table>");
Response.Write("<tr>");
Response.Write("<td>");
Response.Write("Hello");
Response.Write("</td>");
Response.Write("</tr>");
Response.Write("</table>");
Response.End();
Now i want to export an excel file with multiple sheets.
How can i accomplish this?
Tehnically speaking this is not export to excel, but you send a html with a wrong headers to trick browser to open this content with excel.
Better use NPOI (xls) or / and EPPlus (xlsx) and fully control your excel export and then you can create new sheets and more.
Update: In this SO answer you can see example of ashx handler that returns excel file that is created from DataTable :
C# create/modify/read .xlsx files
Related
I created a PDFViewer form in ASP.NET, and it works fine within the app. In the last part of the code, I use these lines to generate the PDF file from information I used previously (I'm using the PDFSharp library):
MemoryStream stream = new MemoryStream();
pdf.Save(stream, false);
response.Clear();
response.ContentType = "application/pdf";
response.AddHeader("content-length", stream.Length.ToString());
response.BinaryWrite(stream.ToArray());
response.Flush();
stream.Close();
response.End();
The file looks good, I see all the PDF browser options to print, zoom, downlad, etc.
The issue I'm having is, when I click on the download button, it wants to download the PDF as "PDFname.aspx", instead of "PDFname.pdf", although I am specifying the content type is "application/pdf". Which other thing could be missing?
I have this method here:
[Authorize]
[HttpPost]
[ValidateInput(false)]
public void ExportCostMatrixExcel(string GridHtmlExcel, string GridCommunityExcel)
{
Response.ClearContent();
Response.ClearHeaders();
Response.BufferOutput = true;
Response.ContentType = "application/excel";
Response.AddHeader("Content-Disposition", "attachment; filename=Reliquat.xlsx");
Response.Write(GridHtmlExcel);
Response.Flush();
Response.Close();
Response.End();
}
This takes me html table and converts it over to an Excel spreadsheet, when I try to open the file, I get this error message:
Excel cannot open the file 'Reliquat.xlsx' because the file format
or file extension is not valid. Verify that the file has not been
corrupted and that the file extension matches the format of the file.
Why is this happening, you can see GridHtmlExcel here on the link below, its an HTML table with colspans, is the colspans messing it up?
https://jsfiddle.net/2nyjhpaz/3/
In essence it looks like you're merely dumping the contents into a file and just renaming it to an XLSX. However, that extension follows a specific XML-based schema, and that's why it doesn't play well.
You have a few options:
Find a library that can do this for you - initial searches list a few but they're often fickle little beings.
Use something like HTML Agility Pack to parse the HTML into a usable format and write it into an excel file. You might have to create an excel file manually, possibly using the Office Interop stuff.
If the excel format itself isn't that much of an issue, you could choose to write a CSV file instead (and can be opened by excel), using CSV Helper - but you'd still have to parse the HTML.
At the top of my page I have the code
<%
Response.ContentType = "text/csv"
Response.AddHeader "Content-Disposition", "attachment;filename=myfile.xls"%>
which forces my table to download as a spreadsheet. But, how can I make certain cells of this download read only ?
Whenever I open an xls file I generated on my ASP.NET page with Excel 2007, I get the following error:
The file you are trying to open, 'filename.xls', is in a different
format than specified by the file extension. Verify that the file is
not corrupted and is from a trusted source before opening the file. Do
you want to open the file now?
If I click 'Yes', everything looks fine, but it's annoying to our customers to have to click through it each time. If they use 2003, no problem, but on 2007 it gives this error. Here's the code I use:
string style = #"<style> .text { mso-number-format: \# } </style> ";
Response.Clear();
Response.AddHeader("content-disposition", string.Format("attachment;filename=OperationsReport_Rejects_{0}.xls", DateTime.Today.ToString("yyyyMMdd")));
Response.Charset = "";
Response.ContentType = "application/vnd.xls";
StringWriter stringWrite = new StringWriter();
HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
reportOperationsRejectsGridView.RenderControl(htmlWrite);
Response.Write(style);
Response.Write(stringWrite.ToString());
Response.End();
Does anyone know what is causing it to behave differently on 2003 and 2007?
Office 2007 uses XML based file formats that are different from the previous binary file formats.
What Excel 2007 saves is not an .xls file, but an .xlsx file.
What you are creating is actually neither. It's an HTML export of an excel file. Some versions will seamlessly import the HTML as an excel document, some versions will warn you that it's actually not an Excel document, before importing it.
If you create an actual .xls file, Excel 2007 will open it in compatibility mode without complaining.
Excel 2003 and 2007 use different formats, unless the user specifically does a "Save As" and chooses a backwardly-compatible format.
A quick look in a hex viewer or hex editor will show you the large difference in the file formats.
SpreadsheetGear for .NET can save as real xls or xlsx workbooks - avoiding this error message.
You can see a number of live samples on our Excel Reporting Samples page here and download the free trial here.
Disclaimer: I own SpreadsheetGear LLC
How can I export the data in my webapp to an Excel sheet from ASP.NET (VB.NET,SQL 2005)?
change the contenttype of your ASP.Net page
Response.ContentType = "application/ms-excel"
One of my most popular blogs is how to generate an Excel document from .NET code, using the Excel XML markup (this is not OpenXML, it's standard Excel XML) - http://www.aaron-powell.com/linq-to-xml-to-excel
I also link off to an easier way to do it with VB 9.
Although this is .NET 3.5 code it could easily be done in .NET 2.0 using XmlDocument and creating the nodes that way.
Then it's just a matter to set the right response headers and streaming back in the response.
SpreadsheetGear for .NET will do it. You can find a bunch of live ASP.NET samples with C# & VB.NET source on this page.
Disclaimer: I own SpreadsheetGear LLC
If you can display your data in a GridView control, it inherently supports "right-click-->Export to Excel" without having to write any code whatsoever.
SQL Server Reporting services would be the best way to export data from an application into Excel.
If you dont have access to / dont wan't to use reporting services depending on the data you want to extract / format possibly using a CSV structure instead of Excel may be easiest.
Use the Microsoft.Office.Interop.Excel dlls to create excel files with your data and then provide links to download the files using Hunter Daley's download method...
As a general solution, you may want to consider writing handler (ashx) for exporting -- and pass either the query parameters to recreate the query to generate the data or an identifier to get the data from the cache (if cached). Depending on whether CSV is sufficient for your Excel export you could just format the data and send it back, setting the ContentType as #Hunter suggests or use the primary interop assemblies (which would require Excel on the server) to construct a real Excel spreadsheet and serialize it to the response stream.
I prefer to use a OLEDB connection string.
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Excel.xls;Extended Properties="Excel 8.0;HDR=Yes;IMEX=1";
Not sure about exporting a page but if you just want to export a dataset or datatable
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", fileName))
HttpContext.Current.Response.ContentType = "application/ms-excel"
Dim sw As StringWriter = New StringWriter
Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
Dim table As Table = New Table
table.RenderControl(htw)
' render the htmlwriter into the response
HttpContext.Current.Response.Write(sw.ToString)
HttpContext.Current.Response.End()
I use almost the same exact code as CodeKiwi. I would use that if you have a DataTable and want to stream it to the client browser.
If you want a file, you could also do a simple loop through each row/column, create a CSV file and I guess provide a link to the client - you can use a file extension of CSV or XLS. Or if you stream the resulting file to the client it will prompt them if they want to open or save it to disk.
The interops are (well were last time I tried them) great for small datasets, but didn't scale well - horrifically slow for larger datasets.