After I downloaded a file using this code:
using (FileStream fileStream = File.OpenRead(filePath))
{
MemoryStream memStream = new MemoryStream();
memStream.SetLength(fileStream.Length);
fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
Response.AddHeader("Content-Disposition", "attachment; filename=" + item.filename);
Response.BinaryWrite(memStream.ToArray());
Response.TransmitFile(filePath);
Response.Flush();
Response.Close();
Response.End();
}
The code works very well, but once I open the docx file after the download it loses its original name and I get the message "the file is corrupt and cannot be opened". this only happened to me with the doc & docx files, I tried for xlsx, jpg, pdf, and it worked very well .
Does this have a relation with my code or is it something else?
I guess your filename has an extension like dotx or dot.
The "t" stands for "Template". The default action for "template" type documents in Microsoft Office is to create a new document from a copy of the template.
Look at the different look of Word document and Word template:
So, if you want the user to download a document and not a template, create a document from the template and send the document to the user with a docx extension.
Related
I've created an endpoint that generates an Excel file. It's supposed to function as a GET in case I want some other code to POST it to a different endpoint for emailing, or in case I want to just download the Excel file by hitting the endpoint manually in a browser. It's downloading the Excel file, but when I try to open it I see the message "Excel cannot open the file 'blahblah' 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."
After getting that error, I've tried changing the MIME type in my response content field and/or file extension, and the error goes away and the file opens with the following warning: "The file format and extension of "blah blah" don't match. The file could be corrupted or unsafe. Unless you trust its source, don't open it. Do you want to open it anyway?" If I open it anyway, the file is still empty.
Here is the code where I take the ExcelPackage I created and add it to the response.
var response = HttpContext.Current.Response;
response.ContentType = "application/vnd.openxmlformats- officedocument.spreadsheetml.sheet";
var fileName = string.Format("blahblah-{0}.xls", InstantPattern.CreateWithInvariantCulture("yyyy-dd-M-HH-mm-ss").Format(_clock.Now));
response.AddHeader("content-disposition", string.Format("attachment; filename={0}", fileName));
response.BinaryWrite(excelPackage.GetAsByteArray());
I've tried adding in a different mime type like application/excel. I've tried using the .xlsx file extension instead of xls. Nothing has really worked. I know that the ExcelPackage workbook's worksheets actually have the data I want, though, because when I debug and hover over the objects I see the cell values that I'm expecting to make it into the file. So what am I doing wrong?
I've tried generating the excelPackage in two ways, both while inside a using block. Like this:
using (var excelPackage = new ExcelPackage())
{
// generate and download excel file
}
And also like this:
using (var excelPackage = new ExcelPackage(new FileInfo(fileName)))
{
// generate and download excel file
}
I use this to send the Excel file to the browser.
HttpResponse Response = HttpContext.Current.Response;
//first convert to byte array
byte[] bin = excelPackage.GetAsByteArray();
//clear the buffer stream
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;
//add the content type
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//set the content length, without it, length is set to -1 and could give errors
Response.AddHeader("content-length", bin.Length.ToString());
//add a filename
Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".xlsx\"");
//send the file to the browser
Response.OutputStream.Write(bin, 0, bin.Length);
//cleanup
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
I have the following code to create a downloadable zip archive that works fine:
ZipFile zip = new ZipFile();
zip.AlternateEncoding = Encoding.UTF8;
zip.AlternateEncodingUsage = ZipOption.Always;
zip.AddFiles(filePaths, false, ".");
string zipName = String.Format("Files_{0}.zip", DateTime.Now.ToString("yyyy-MMM-dd"));
Response.Clear();
Response.BufferOutput = false;
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "attachment; filename=" + zipName);
zip.Save(Response.OutputStream);
Response.End();
users usually open files within a zip archive without extracting that. unfortunately I cannot open a file without extracting when using above code to create a zip archive. when trying to open a file an extra window appears shown as below:
I tried both two namespaces: Ionic.Zip and SharpCompress and the problem appears in either one.
any help would be appreciated. tks
Your code is correct but keep in mind that XLSX file format is a zip file.
What happened, is that WinRAR treats it as an archive and just unpacks it.
You can configure WinRAR and tell it to open xlxs files using Excel.
Go to
Options -> Settings -> Viewer and select Excel as an Associated Program for *.xlsx
http://acritum.com/software/manuals/winrar/html/helpviewersettings.htm
I have created a PDF using iText and storing it in a particular location (specified in the code). I would like to prompt a save dialog box for the user to choose location on his computer to save the pdf. I checked iText tutorial but it didn't help me.
Here is the code for generating the PDF file:
Document objDoc = new Document();
PdfWriter.GetInstance(objDoc, new FileStream("C:\\HelloWorld.pdf", FileMode.Create));
objDoc.Open();
objDoc.Add(new Paragraph("welcome iText Pdf"));
objDoc.Close();
I tried like this for saving:
string FileName ="HelloWorld.pdf";
String FilePath = #"C:\";
HttpResponse response = HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "application/pdf";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath + FileName);
response.Flush();
response.End();
I'm assuming you're doing this from a web page since you tagged this ASP.NET. You need to add the Content-Disposition header. See the following question for details:
Force download of a file on web server - ASP .NET C#
I have generated a pdf using iTextSharp, when its created it saves automatically in the location provided in my code on the server not on the client side and of course without telling anything to the user.
I need to send it to the client and I need to prompt a dialogue box to ask the user where he wants to save his pdf..
how can i do this please?
this is my pdf code:
using (MemoryStream myMemoryStream = new MemoryStream())
{
Document document = new Document();
PdfWriter PDFWriter = PdfWriter.GetInstance(document, myMemoryStream);
document.AddHeader("header1", "HEADER1");
document.Open();
//..........
document.Close();
byte[] content = myMemoryStream.ToArray();
// Write out PDF from memory stream.
using (FileStream fs = File.Create(HttpContext.Current.Server.MapPath("~\\report.pdf")))
{
fs.Write(content, 0, (int)content.Length);
}
EDIT
this is an example of the result i want
http://examples.extjs.eu/?ex=download
thanks to your replies ,I modified my code to this:
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AppendHeader( "Content-Disposition", "attachment; filename=test.pdf");
using (MemoryStream myMemoryStream = new MemoryStream())
{
Document document = new Document();
PdfWriter PDFWriter = PdfWriter.GetInstance(document, myMemoryStream);
document.AddHeader("Content-Disposition", "attachment; filename=wissalReport.pdf");
document.Open();
//..........
document.Close();
byte[] content = myMemoryStream.ToArray();
HttpContext.Current.Response.Buffer = false;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.AppendHeader("content-disposition","attachment;filename=" + "my_report.pdf");
HttpContext.Current.Response.ContentType = "Application/pdf";
//Write the file content directly to the HTTP content output stream.
HttpContext.Current.Response.BinaryWrite(content);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
but i get this error:
Uncaught Ext.Error: You're trying to decode an invalid JSON String:
%PDF-1.4 %���� 3 0 obj <</Type/XObject/Subtype/Image/Width 994/Height 185/Length 13339/ColorSpace/DeviceGray/BitsPerComponent 8/Filter/FlateDecode>>stream x���|E�
...........
im absolutely sure my itextsharp to create pdf is correct because i can save it on the server, but thats not what i need to do ,when i try to send it to the client i got the error above
thanks in advance
In case of a web application you probably want to stream the pdf as binary to user, that would either open the pdf or prompt user to save the file.
Remember pdf generation is happening at server, even if user provides the path it won't be of any use on server. See following links -
How To Write Binary Files to the Browser Using ASP.NET and Visual C# .NET
In your case you are generating the file and hence will already be having a binary stream instead of file, hence you can directly use Response.BinaryWrite instead of Response.WriteFile.
Modified sample:
Response.Buffer = false;
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
//Set the appropriate ContentType.
Response.ContentType = "Application/pdf";
//Write the file content directly to the HTTP content output stream.
Response.BinaryWrite(content);
Response.Flush();
Response.End();
You need to send a content disposition header to the users browser. From memory the code is something sort of like this:
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition","attachment; filename=nameofthefile.pdf");
Currently you are saving your file on the file server, thereby overwriting the same pdf with every request. And probably causing errors if you get two requests for a PDF at the same time.
Use Response to return the PDF (from the memorystream) to the user, and skip the writing of the PDF to a file locally on your server.
The browser will ask the user where the file should be saved. Something like:
Response.ContentType = "Application/pdf";
myMemoryStream.CopyTo(Response.OutputStream);
Also look at the answer from Alun, using content-disposition you can propose a filename to the user.
SOLVED
The error is from the submit operation trying to interpret the response which it can not because it is not in a known format.
I just set window.location to download files and this works fine.
{
xtype:'button',
text: 'Generate PDF',
handler: function () {
window.location = '/AddData.ashx?action=pdf';
}
}
Instead of setting the location you can also do window.open().
Whether the file will be downloaded or opened depends on browser settings.
You do not need to use MemoryStream. Use Response.OutputStream instead. That's what it's there for. No need to use Response.BinaryWrite() or any other call to explicitly write the document either; iTextSharp takes care of writing to the stream when you use Response.OutputStream.
Here's a simple working example:
Response.ContentType = "application/pdf";
Response.AppendHeader(
"Content-Disposition",
"attachment; filename=test.pdf"
);
using (Document document = new Document()) {
PdfWriter.GetInstance(document, Response.OutputStream);
document.Open();
document.Add(new Paragraph("This is a paragraph"));
}
Here's how to add the proper HTTP headers. (getting the prompt to save the file) And if your code is in a web form, (button click handler), add Response.End() to the code example above after the using statement so that the web form's HTML output is not appended the PDF document.
I am trying to export the HTML page contents to Word.
My Html display page is:
What is your favourite color?
NA
List the top three school ?
one National
two Devs
three PS
And a button for click event. The button click event will open MS word and paste the page contents in word.
The word page contains the table property of html design page. It occurs only in Word 2003. But in word 2007 the word document contains the text with out table property. How can I remove this table property in word 2003.
I am not able to add the snapshots. Else i will make you clear.
I am designing the web page by aspx. I am exporting the web page content by the following code.
protected void Button1_Click(object sender, EventArgs e)
{
Response.ContentEncoding = System.Text.Encoding.UTF7;
System.Text.StringBuilder SB = new System.Text.StringBuilder();
System.IO.StringWriter SW = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlTW = new System.Web.UI.HtmlTextWriter(SW);
tbl.RenderControl(htmlTW);
string strBody = "<html>" +
"<body>" + "<div><b>" + htmlTW.InnerWriter.ToString() + "</b></div>" +
"</body>" +
"</html>";
Response.AppendHeader("Content-Type", "application/msword");
Response.AppendHeader("Content-disposition", "attachment; filename=" + fileName);
Response.ContentEncoding = System.Text.Encoding.UTF7;
string fileName1 = "C://Temp/Excel" + DateTime.Now.Millisecond.ToString();
BinaryWriter writer = new BinaryWriter(File.Open(fileName1, FileMode.Create));
writer.Write(strBody);
writer.Close();
FileStream fs = new FileStream(fileName1, FileMode.Open, FileAccess.Read);
byte[] renderedBytes;
// Create a byte array of file stream length
renderedBytes = new byte[fs.Length];
//Read block of bytes from stream into the byte array
fs.Read(renderedBytes, 0, System.Convert.ToInt32(fs.Length));
//Close the File Stream
fs.Close();
FileInfo TheFile = new FileInfo(fileName1);
if (TheFile.Exists)
{
File.Delete(fileName1);
}
Response.BinaryWrite(renderedBytes);
Response.Flush();
Response.End();
}
You are writing HTML, claiming it is of content type "application/msword", then hoping for the best..
There are more "correct" ways to achieve your objective.
There are a few projects around for converting (X)HTML to WordML content, of which docx4j-ImportXHTML.NET is one. Disclosure: I maintain that; you can find links to others elsewhere here on StackOverflow.
Alternatively, you can use Word's altChunk mechanism, though note:
you have less control over how the import is performed;
AltChunk isn't supported by Word 2003 (even with the compatibility pack).
Question not clear.
Well, these links may help you in understanding MSWord-C# automation:
http://www.codeproject.com/KB/cs/Simple_Ms_Word_Automation.aspx
http://www.c-sharpcorner.com/UploadFile/amrish_deep/WordAutomation05102007223934PM/WordAutomation.aspx
You can also try to create an Open XML document that is now recognized by MS office.
Here is some more info with code samples:
http://msdn.microsoft.com/en-us/library/bb656295.aspx
From what I understand, you are trying to create a ms word document on the fly and are having difficulty when the output is viewed in Word 2003 vs. 2007.
In your code above, you are simply spitting out html and forcing it to be a ms word document. I'm surprised it even works.
Instead, you might want to use Office Interop (Microsoft.Office.Interop.Word) or install DocX using nuget. Look at some examples online, search for "C# create word doc".