I am exporting the HTML Content to PDF.
System.IO.StringWriter sWriter = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWriter = new HtmlTextWriter(sWriter);
Response.Buffer = true;
FormId.RenderControl(htmlWriter);
Response.ContentType = "application/pdf";
// Added appropriate headers
Response.AddHeader("Content-Disposition", "inline; filename=XXX.pdf");
Response.AddHeader("Content-Length", htmlWriter.ToString().Length.ToString());
Response.Output.Write(sWriter.ToString());
Response.Flush();
Response.Close();
FormId is my Div past of the content..
I am getting the error as "File does not begin with '%PDF-'"
I have included Response.clear(); The output is not coming
You're rendering out the html (div as you said) before the pdf in the output stream, so the two are combined. That's causing any app looking at the output to interpret it as a corrupted file. I'd try removing the first two lines:
Response.Buffer = true;
FormId.RenderControl(htmlWriter);
If that doesn't solve the issue, add a Response.Clear() call before everything.
This is all assuming sWriter contains the PDF at the beginning of this code block -- if not, a little more context might be helpful.
Some advice: if at all possible, move this out of the page to a .ashx or other IHttpHandler.
I was facing the same issue while writing some HTML content to PDF.
I finally found that invalid HTML content causes this issue.
For example, <ul> tag without closing tag </ul>.
Once I put in the proper closing tags, it works fine!
Do a Response.Clear() before starting to stream your output.
Related
Using a memory stream & the correct MIME type with Response.ContentType. Special characters are displayed instead of prompting to open a Word document. I'm using:
using (MemoryStream ms = new MemoryStream())
{
doc.SaveAs(ms);
Response.Clear();
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", fileName));
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
ms.WriteTo(Response.OutputStream);
Response.End();
}
Here's an example of the output I get now rather than a prompt to open a Word document:
Turns out it was not a MIME or Response.ContentType issue at all. Being an MVC application, I was attempting to open the FileResult in a modal. Copy/Paste fail, as other buttons worked this way to display content. Not a Word document!
In ASP.Net, I'm using NPOI to write save to an Excel doc and I've just moved to version 2+. It worked fine writing to xls but switching to xlsx is a little more challenging. My new and improved code is adding lots of NUL characters to the output file.
The result is that Excel complains that there is "a problem with some content" and do I want them to try to recover?
Here is a pic of the xlsx file that was created from my Hex editor:
BadXlsxHexImage Those 00s go on for several pages. I literally deleted those in the editor until the file opened without an error.
Why does this code add so many NULs to this file??
using (var exportData = new MemoryStream())
{
workbook.Write(exportData);
byte[] buf = exportData.GetBuffer();
string saveAsFileName = sFileName + ".xlsx";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}; size={1}", saveAsFileName, buf.Length.ToString()));
Response.Clear();
Response.OutputStream.Write(buf, 0, buf.Length);
exportData.Close();
Response.BufferOutput = true;
Response.Flush();
Response.Close();
}
(I've already tried BinaryWrite in place of OutputStream.Write, Response.End in place of Response.Close, and setting Content-Length with the length of the buffer. Also, none of this was an issue writing to xls.)
The reason you are getting a bunch of null bytes is because you are using GetBuffer on the MemoryStream. This will return the entire allocated internal buffer array, which will include unused bytes that are beyond the end of the data if the buffer is not completely full. If you want to get just the data in the buffer (which you definitely do), then you should use ToArray instead.
That being said, why are you writing to a MemoryStream at all? You already have a stream to write to: the OutputStream. Just write the workbook directly to that.
Try it like this:
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", saveAsFileName));
workbook.Write(Response.OutputStream);
Response.Flush();
Response.Close();
I try to download a docx file from serverside.
What is my wrong ?
this is code :
FileInfo file = new FileInfo(filepath);
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.AppendHeader("Content-Disposition", "attachment; filename = " + ((Button)sender).CommandName + ".docx");
Response.AppendHeader("Content-Length", file.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(file.FullName);
Response.Flush();
Response.Close();
Response.End();
I have posted something similar in another question for an PDF but here goes. It's much easier to stream this sort of data back through an ASHX handler.
Something like what I posted in this question but with a docx file.
Display PDF in iframe
It looks like you are using a normal ASP.NET page and are trying to modify the standard behavior by clearing out the headers, etc. You won't have to fiddle with the headers or anything like that with an ashx handler.
I am writing a webapplication in ASP.net.
I am trying to make a file dialog box appear for downloading something off the server.
I have the appropriate file data stored in a variable called file.
File has fields:
FileType - The MIMEType of the file
FilePath - The server-side file path
Here's the code so far:
Response.Clear();
Response.ContentType = file.FileType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + GetFileName(file));
Response.TransmitFile(file.FilePath) ;
Response.End();
GetFileName is a function that gets me the filename from an attachment object. I only store the path.
The above code is in a function called "Download_Clicked" that is an event that triggers on click. The event is mapped to a LinkButton.
The problem is that when I run the above code, nothing happens. The standard dialog box does not appear.
I have attempted the standard trouble-shooting such as making sure the file exists, and ensuring the path is correct. They are both dead on the mark.
My guess is that because my machine is also the server, it may not be processing properly somehow.
Thanks in advance.
Edit 1: Attempted putting control onto another page, works fine.
Edit 2: Resolved issue by removing control from AJAX Update Panel.
I've found another to do this without removing the update panel. Place the code below in your page load and you'll now be able to use that button to trigger a download.
ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(Button);
Use Response.WriteFile() instead.
Also, don't use Response.End()! This aborts the thread. Use Response.Flush(); Response.Close();
Try changing
Response.AppendHeader("Content-Disposition", "attachment; filename=" + GetFileName(file));
To
Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(GetFileName(file))));
If that doesn't work, you can always use Response.BinaryWrite or Resonse.Write to stream the file to the web browser
Here is how transmit the file using Response.Write or Response.BinaryWrite. Put these functions in a library somewhere then call them as needed
public void SendFileToBrowser(String FileName, String MIMEType, String FileData)
{
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName);
Response.ContentType = MIMEType;
Response.Buffer = true;
Response.Write(FileData);
Response.End();
}
public void SendFileToBrowser(String FileName, String MIMEType, Byte[] FileData)
{
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName);
Response.ContentType = MIMEType;
Response.Buffer = true;
Response.BinaryWrite(FileData);
Response.End();
}
Then somewhere you call these functions like so
SendFileToBrowser("FileName.txt", "text/plain", "Don't try this from an Update Panel. MSAjax does not like it when you mess with the response stream.");
See edit on initial post.
Removed Ajax Update Panel to resolve the error. The panel was stopping the post back to the server.
For more info, see Cris Valenzuela's comment.
I am trying to export my repeater to excel and here is my code...
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
string attachment = "attachment; filename=file.xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/vnd.ms-excel";
rpt.RenderControl(htw);
Response.Write(sw.ToString());
Response.Flush();
Response.End();
When I am trying to open file getting this error
The file you are trying to open, 'file.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?
Yes No Help option are available
What's wrong in my code or What I have to do resolve this issue.
Thanks
You are setting the content type to application/vnd.ms-excel but you are sending HTML contents in the response stream when you call the RenderContents method. You might need a library to generate Excel files.
Try wrapping your content into this:
StringBuilder sb = new StringBuilder("");
sb.Append("<HTML xmlns:x=\"urn:schemas-microsoft-com:office:excel\"><HEAD>");
sb.Append("<meta http-equiv=Content-Type content=\"text/html; charset=utf-8\">");
sb.Append("<!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>");
sb.Append(title);
sb.Append("</x:Name><x:WorksheetOptions><x:Print><x:ValidPrinterInfo/></x:Print></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--> </HEAD><BODY>");
sb.Append(content);
sb.Append("</BODY></HTML>");