I have to export some data from an asp.net page to excel, so I use basically a table to create the custom headers I need then a GridView. All the data displays correctly when exported to excel, but when I added an Logo image to the html, it doesn't show up on the Excel file when exported.
Since I need to export it to Excel 2007 or later, I know I can use the Open XML stuff from Microsoft to export the data, the problem is that I already have everything done on the code and I wanted to know if there is another way to do that instead of doing all over again using Open XML.
If there isn't a way to do that without using Open XML, can anyone show me how I could export the data to it? I tried once but I didn't have much success. =/
BTW, I'm using C#.
Thanks in advance!
I've updated the code and now it looks like this, but I still can't see the image... =/
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
frmPlanoAcao.RenderControl(htmlWrite);
StringWriter w = new StringWriter();
HtmlTextWriter t = new HtmlTextWriter(w);
imgLogo.RenderControl(t);
var byte_array = System.Text.Encoding.ASCII.GetBytes(w.ToString());
Response.Write(stringWrite.ToString());
this.EnableViewState = false;
Response.Clear();
Response.Buffer = false;
Response.Charset = "ISO-8859-1";
Response.ContentEncoding = System.Text.Encoding.GetEncoding(1252);
Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", "plano_acao.xls"));
Response.ContentType = "application/vnd.ms-excel";
Response.Write("<meta http-equiv=Content-Type content=\"text/html; charset=utf-8\">");
Response.Write(getExcelStyling());
Response.OutputStream.Write(byte_array, 0, byte_array.Length);
Response.Write(stringWrite.ToString());
Response.Write("</body>");
Response.Write("</html>");
Response.End();
Try the following code. I have tested at local IIS and it is working properly.
Including the image like Header Image/Logo on top of the grid data.
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "attachment; filename=test.xls;");
StringWriter stringWrite = new StringWriter();
HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
dgrExport.DataSource = dtExport;
dgrExport.DataBind();
dgrExport.RenderControl(htmlWrite);
string headerTable = #"<Table><tr><td><img src=""D:\\Folder\\1.jpg"" \></td></tr></Table>";
Response.Write(headerTable);
Response.Write(stringWrite.ToString());
Response.End();
you can customize your image's height and width as per your requirement. Same height and width setting will be required for the <TD> tag.
You have to get images in StringWriter and use System.Text.Encoding.ASCII.GetBytes(stringwriter string) in array of bytes.
then write these as outputStream.Write(byte_array, 0, byte_array.Length);
where outputstream is HttpContext Response outputstream.
If you say, to convert Grid, Images, everything in one go to Excel, i have not tried. But, i can say, you can individually have both of them into Excel by their way.
If you are using C# and want to export to Excel I would recommend EPPLUS
http://epplus.codeplex.com/
Will save you a whole lot of troubles now and in the future.
Related
I want to make a button that makes the download of a DataTable object using an HTTP request.
I already have this code that can print .xls files by changing the contentType as indicated in comment.
However, this does not work with xlsx file.
private void DownloadExcel(DataSet ds, string excelFileNameNowDateTime)
{
System.IO.StringWriter tw = new System.IO.StringWriter(); ;
System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
System.Web.UI.WebControls.DataGrid dgGrid = new System.Web.UI.WebControls.DataGrid();
dgGrid.DataSource = ds.Tables[0];
// Get the HTML for the control.
dgGrid.HeaderStyle.Font.Bold = false;
dgGrid.DataBind();
dgGrid.RenderControl(hw);
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//string contentType = "application/vnd.ms-excel";
Response.ContentType = contentType;
this.EnableViewState = true;
Response.Clear();
//Response.ContentEncoding = System.Text.Encoding.Default;
Response.AddHeader("content-disposition", String.Format(#"attachment; filename={0}", excelFileNameNowDateTime + ".xlsx"));
Response.Write(tw.ToString());
CloseHTTPResponse();
}
While opening the file is giving me the error
Excel cannot open the file .xlsx because the file format is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.
Any idea on why this does not work?
It looks to me like you're trying to send HTML contents with .xlsx extension. This won't work since XLSX is fundamentally not HTML, but zipped XML with quite specific (and convoluted) schema. The simplest way to achieve your goal would be to use one of the existing 3rd party libraries that can generate XLSX on the fly. I personally had used ClosedXML for a similar task, but there are many other options at NuGet.
This code doesn't produce an Excel file, it produces an HTML file with a fake extension. Excel won't be fooled, it will try to import this HTML file using the user locale's defaults. This will easily lead to problems if the decimal separator is different or the cells contain text that interferes with HTML.
There's no reason for such code. XLSX is a ZIP package containing well-formed XML files. You can use the Open XML SDK to create Excel files at a low level or you can use libraries like EPPlus (57M downloads), ClosedXML (27M), NPOI (22M) and more, to create real Excel files.
With EPPlus, creating an Excel file from a DataTable is really a single command, sheet.Cells.LoadFromDataTable(dt);
public byte[] Export(DataTable dt)
{
using (var p = new ExcelPackage())
{
var ws = p.Workbook.Worksheets.Add("SomeSheet");
var table=ws.Cells.LoadFromDataTable(dt);
var excelData = package.GetAsByteArray();
return excelData;
}
}
After that, you write the output to the Response stream :
var bytes = Export(dt);
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", $"attachment;filename={excelFileNameNowDateTime}.xlsx");
Response.BinaryWrite(bytes);
Response.End();
For ASP.NET (no .NET Core Required solution).
using ClosedXML.Excel;
private void DownloadExcelClosedXML(DataTable dt)
{
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add(dt);
using (var stream = new MemoryStream())
{
workbook.SaveAs(stream);
var content = stream.ToArray();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheet.sheet";
Response.AddHeader("content-disposition", "attachment; filename=name_you_file.xlsx");
Response.BinaryWrite(content);
Response.End();
}
}
}
The following code exports some data, downloading it in an XLS file.
What I want is to give all the three list and export each list of data in a separate sheet. How can I do that?
My code looks like this:
public bool ExportQuestionSet(int QuestionSetNo)
{
ExportResponse response = new ExportResponse();
QuestionSetTbl questionSetTbl = _questionSetDAO.GetQuestionSetByQuestionSetNo(QuestionSetNo);
QuestionSetContract questionSetContract = GetQuestionSetByQuestionSetNo(QuestionSetNo);
GridView gv = new GridView();
gv.DataSource = questionSetContract.QuestionsInfoList;
gv.DataBind();
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=QuestionSet.xls");
Response.ContentType = "application/ms-excel";
Response.Charset = "";
StringWriter sw = new StringWriter();
System.Web.UI.HtmlTextWriter htw = new System.Web.UI.HtmlTextWriter(sw);
gv.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
return response.TaskComplete;
}
You can't output HTML and call it Excel. This works well for a reasonably formatted table, but it isn't an Excel file and will never be recognized as such. The file can be read, but it isn't possible to export multiple sheets.
Use a library to create a proper Excel file.
I would suggest using OpenXml, as it's quite fast and will create the correct Excel file. Using the sample in this thread: https://stackoverflow.com/a/11812551/1361993 you can just create a dataset with multiple datatables, which will in turn be outputted to the respective sheets in the file.
i have been trying export grid view to doc . and facing issues .
List of data contains data from database in from of List<>.
GridView GridView1 = new GridView();
GridView1.AllowPaging = false;
GridView1.DataSource = ListofData;
GridView1.DataBind();
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=Export-Grid.doc");
Response.Charset = "";
Response.ContentType = "application/vnd.word";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
GridView1.RenderControl(htw);
Response.Write(sw.ToString());
Response.Flush();
Response.End();
problem with this approach is
1) when i open Export-Grid.doc in Office 2013 it prompts me that u want to open file as HTml Document , PDF document etc . if i try to open document using HTML it writes all data in file but in html form and if i use Plain text option it do same thing writes html data.
2) if i try to open Export-Grid.doc using open office it open the document but columns width is to big
i m using asp.net mvc. can some one help me how can i fix this or let me know wat m doing wrong ???
any help will be appreciated
I have copied code previously used throughout the system i am working on. However this code opens the content in a word document. I am looking it to be opened in a PDF.
I have already tried changing the string declaration 'filename' to end in (.pdf) as opposed to (.doc) but when attempting to open it it says "could not open the document because it is either not a spported file type or because the file has been damaged....".
What changes need to be made to this code in order to open it as an adope pdf. I wouldnt imagine it would be alot.
string content = sw.GetStringBuilder().ToString();
string fileName = "IRPBestPracticeArticle.doc";
Response.AppendHeader("Content-Type", "application/msword; charset=utf-8");
Response.AppendHeader("Content-disposition", "attachment; filename=" + fileName);
Response.Charset = "utf-8";
Response.Write(content);
I cannot say for certain, but I am going to assume you're trying to save your data as a pdf and have it open in whatever application the system uses to read pdf files?
//Note the change from application/msword to application/pdf
Response.AppendHeader("Content-Type", "application/pdf; charset=utf-8");
Make sure to change the mime type as well as the doc ending (See here for full list of mime types):
That being said, I cant guarantee it will open properly in your PDF reader
Just try this set of code.
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "inline;filename=" + fileName);
Response.ContentType = "application/pdf";
Response.WriteFile("FullFilePath");
Response.Flush();
Response.Clear();
Response.End();
The mime type need to be set correctly before opening the file.
Andy try this one. You must have ItextSharp.dll to use this code. Download it from here. Then add its reference in your page.
try this code to create pdf from string and download it
Document document = new Document(PageSize.A4);
using (MemoryStream ms = new MemoryStream())
{
PdfWriter.GetInstance(document, ms);
document.Open();
System.Xml.XmlTextReader _xmlr;
if (String.IsNullOrEmpty(errorMsg))
_xmlr = new System.Xml.XmlTextReader(new StringReader(GetTransferedData(content)));
else
_xmlr = new System.Xml.XmlTextReader(new StringReader(#"<html><body>Error Message:" + errorMsg + "</body></html>"));
iTextSharp.text.html.HtmlParser.Parse(document, _xmlr);
document.Close();
ms.Flush();
byte[] data = ms.ToArray();
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.BinaryWrite(data);
Response.End();
ms.Close();
}
First, convert the .doc files to PDF files. Here is a sample of how to achieve this: Convert Doc file to PDF in VB.Net
After you have the PDF files, stream them to the browser using the "application/pdf" content type.
Is it possible to save an exported word document file using Response.Write(). Now it's showing Save/Open dialog box, once it Converted successfully. But i need to save this file to a folder. Please help me for resolve this issue.
My conversion to Doc code is appended below.
private void ExportDataSetToWordDoc()
{
try
{
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", DateTime.Today.ToShortDateString().Replace("/", "").Replace("-", "") + "_" + DateTime.Now.ToShortDateString() + ".doc"));
Response.ContentType = "application/ms-word";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
tblMain.RenderControl(htw);
Response.Write(sw.ToString());
Response.End();
}
catch (ThreadAbortException ex)
{
Common.LogError(ex);
}
}
It's up to the Browser to offer the user an "open or save" option. That's what your content-disposition "attach" is encouraging the browser to do. Your other option is content-disposition "inline", where the browser will usually just call up the application (Word in this case) to open the file. See MSDN.
Sadly, the browser will not always offer the filename you specified as the default filename in the "Save As" dialog. Often it will offer the name of your web page as the default instead. Firefox at least documents this as a bug, IE seems to think it is a "feature".
I have modified my code as shown below. Now its saving the specified folder
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", DateTime.Today.ToShortDateString().Replace("/", "").Replace("-", "") + "_" + DateTime.Now.ToShortDateString() + ".doc"));
Response.ContentType = "application/ms-word";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
tblMain.RenderControl(htw);
string strPath = Request.PhysicalApplicationPath + "Test.doc";
StreamWriter sWriter = new StreamWriter(strPath);
sWriter.Write(sw.ToString());
sWriter.Close();
Thanks.
You can use a stream writer (System.IO.StreamWriter) using a path.
When the stream writer will be closed, the file will be saved on at the specified path.
But, it will save on the server disk. If you want to save on the client side, you don't have other choice than ask the user where to put the file. You can't save files on a client without its approval.
var x = new System.IO.StreamWriter(path);
x.Close();