Download PDF without saving in ASP.net Handler - c#

I've a handler in asp.net app. When there comes some kind of request I want user to get download window, where I put PDF stream. I don't want PDF to be saved in memory.
I have the following code, but it fails to open, says pdf file was demaged and couldn't open it.
tell me other way to achieve my goal if you think mine is not good.
MemoryStream stream = new MemoryStream();
CreatePFD(T.Text, stream);
context.Response.Write(stream);
context.Response.ContentType = "application/pdf";
context.Response.AddHeader("content-disposition", "attachment; filename=" + "Nots__Saved__FIle__fileName.pdf");
Now I have this code:
Document Doc = new Document(PageSize.A4, 80, 50, 30, 65);
System.IO.Stream outputStream = new System.IO.FileStream(#"C:\inetpub\wwwroot\c\wefwe.pdf", System.IO.FileMode.OpenOrCreate);
PdfWriter.GetInstance(Doc, outputStream);
Doc.Open();
List<IElement> htmlarraylist = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(new StringReader(T.Text), null);
for (int k = 0; k < htmlarraylist.Count; k++)
{
Doc.Add((IElement)htmlarraylist[k]);
}
outputStream.CopyTo(context.Response.OutputStream);
Doc.Close();
context.Response.ContentType = "application/pdf";
context.Response.AddHeader("content-disposition", "attachment; filename=" + "Nots__Saved__FIle__fileName.pdf");
when i save pdf, the file is correct...
but when I get response the file is in correct. demaged...

You need to rewind the stream by setting stream.Position = 0.
Also, Response.Write(stream) will just print stream.ToString().
Instead, you should call stream.CopyTo(Response.OutputStream).

Related

Post Back not occuring after pdf is downloaded

I've developed a pdf file using itextsharp.
Pdf generation is working fine. After the pdf is created it's being downloaded.
My problem is when the user clicks on Generate PDF button , Pdf is generated and downloaded properly but postback doesn't occurs.
I want the postback to be occured because I want to Reset my Form after Pdf is generated that is Clear All Fields .
How Can I do this ?
Here is my code :
Method to Generate PDF :
public void GetPDF(string quote_num)
{
string url = FilesPath.Path_SaveFile + Session["empcd"].ToString() +"-Quotation.pdf";
Document disclaimer = new Document(PageSize.A4, 2, 2, 10, 10);
PdfWriter writer = PdfWriter.GetInstance(disclaimer, new FileStream(url, FileMode.Create));
writer.PageEvent = new myPDFpgHandler(quote_num);
disclaimer.SetMargins(70, 10, 60, 80);
disclaimer.Open();
GenerateQuotPDF getpdf = new GenerateQuotPDF();
disclaimer = getpdf.GetPDFparams(disclaimer,quote_num, Session["empcd"].ToString(),txt_contactperson.Text,txt_contact1.Text,txt_company.Text,txt_address.Text,ddl_gene_desc.SelectedItem.ToString(),ddl_canopy.SelectedItem.ToString(),ddl_gene_type.SelectedItem.ToString(),txt_rentalamount.Text,txt_hours.Text,txt_variable.Text,ddl_terms.SelectedItem.ToString(),txt_remarks.Text,txt_technical.Text,ddl_sign1.SelectedValue,ddl_sign2.SelectedValue,txt_designation.Text,DateTime.Now);
disclaimer.Close();
System.IO.FileInfo file = new System.IO.FileInfo(url);
if (file.Exists)
{
WebClient client = new WebClient();
Byte[] buffer = client.DownloadData(url);
Response.AddHeader("content-disposition", "attachment; filename=" + Session["empcd"].ToString() + "-Quotation.pdf");
Response.AddHeader("content-length", buffer.Length.ToString());
Response.ContentType = "application/pdf";
Response.BinaryWrite(buffer);
}
}
Generate PDF Button Code :
protected void btn_submit_Click(object sender, EventArgs e)
{
if (IsValidQuotation())
{
string newQuotNum = rental_quotations.GetNewQuotNumber();
rental_quotations.AddNewQuotation(newQuotNum, Session["empcd"].ToString(), ddl_gene_type.SelectedValue.ToString(), ddl_gene_desc.SelectedValue, ddl_canopy.SelectedValue, txt_company.Text, txt_address.Text, txt_contactperson.Text, txt_designation.Text, txt_contact1.Text, txt_contact2.Text, txt_rentalamount.Text, ddl_terms.SelectedValue, txt_hours.Text, txt_variable.Text, txt_remarks.Text,ddl_sign1.SelectedValue,ddl_sign2.SelectedValue,txt_technical.Text);
GetPDF(newQuotNum);
ClearAllFields(); //this is not working
}
}
Postback is occurring since the file is being created. Try the given solution. Your GetPDF(string quote_num) function is doing two tasks that you should break into two functions.
Creating the pdf document.
Downloading the pdf file after it is done.
Now, After you have created the document, you should clear the controls and then send the file as response. Therefore do it as follows:
Create pdf file.
public void CreatePDF(string quote_num)
{
string url = FilesPath.Path_SaveFile + Session["empcd"].ToString() +"-Quotation.pdf";
Document disclaimer = new Document(PageSize.A4, 2, 2, 10, 10);
PdfWriter writer = PdfWriter.GetInstance(disclaimer, new FileStream(url, FileMode.Create));
writer.PageEvent = new myPDFpgHandler(quote_num);
disclaimer.SetMargins(70, 10, 60, 80);
disclaimer.Open();
GenerateQuotPDF getpdf = new GenerateQuotPDF();
disclaimer = getpdf.GetPDFparams(disclaimer,quote_num, Session["empcd"].ToString(),txt_contactperson.Text,txt_contact1.Text,txt_company.Text,txt_address.Text,ddl_gene_desc.SelectedItem.ToString(),ddl_canopy.SelectedItem.ToString(),ddl_gene_type.SelectedItem.ToString(),txt_rentalamount.Text,txt_hours.Text,txt_variable.Text,ddl_terms.SelectedItem.ToString(),txt_remarks.Text,txt_technical.Text,ddl_sign1.SelectedValue,ddl_sign2.SelectedValue,txt_designation.Text,DateTime.Now);
disclaimer.Close();
}
Reset the controls.
ClearAllFields();
Send the file as response.
public void SendPDF(string url)
{
System.IO.FileInfo file = new System.IO.FileInfo(url);
if (file.Exists)
{
WebClient client = new WebClient();
Byte[] buffer = client.DownloadData(url);
Response.AddHeader("content-disposition", "attachment; filename=" + Session["empcd"].ToString() + "-Quotation.pdf");
Response.AddHeader("content-length", buffer.Length.ToString());
Response.ContentType = "application/pdf";
Response.BinaryWrite(buffer);
Response.End();
}
}
Note that I also added Response.End() to clear the buffer.

iTextSharp generating corrupt PDF as "pdf.pdf"

I have this simple piece of code which I took from another question here with the same topic, corrupted PDF files.
I've tried to implement the described solution, along with other references, but have met no sucess yet.
Here are the two functions generating my example PDF:
private void ShowPdf (byte[] str)
{
var Response = HttpContext.Current.Response;
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=" + DateTime.Now);
Response.BinaryWrite(str);
Response.End();
Response.Flush();
Response.Clear();
}
private byte[] CreatePDF2()
{
Document doc = new Document(PageSize.LETTER, 50, 50, 50, 50);
using (MemoryStream output = new MemoryStream())
{
PdfWriter wri = PdfWriter.GetInstance(doc, output);
doc.Open();
Paragraph header = new Paragraph("Test bug") { Alignment = Element.ALIGN_CENTER };
Paragraph paragraph = new Paragraph("test.");
Phrase phrase = new Phrase("testnewline. \nnewline hapenned.");
Chunk chunk = new Chunk("Chucnk cauncuanocnaacoocsinasiocniocsanacsoi chunk.");
doc.Add(header);
doc.Add(paragraph);
doc.Add(phrase);
doc.Add(chunk);
doc.Close();
return output.ToArray();
}
}
Then at an request, I just consume it as in:
ShowPdf(CreatePDF2());
The problem is that this generates a file called "Response.pdf.pdf", which is corrupt and can't be opened.
How can I solve this problem?
Obs.: I am currently using iTextSharp 4.1.6
Try this for output variable,
FileStream output = new FileStream(Server.MapPath("MyFirstPDF.pdf"), FileMode.Create);

How to have Internet Explorer hold on to a stream?

I am streaming a CSV file to Internet Explorer. At the end of the streaming, Internet Explorer presents an Open, Save, and Cancel dialog. If you wait 30 seconds after the dialog is presented and click the Open button, Internet Explorer does nothing. This works fine in Firefox. Do I need some other command besides Flush and End on the Response? Here is the code that I have:
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = ReportService.GetAllOwnerAircraftPaymentInformation();
//Generate the report
using (MemoryStream stream = new MemoryStream())
{
StreamWriter writer = new StreamWriter(stream);
CsvHelper csvHelper = new CsvHelper();
csvHelper.DataTableToCsv(writer, dt);
writer.Flush();
//Send it to the browser
stream.Seek(0, SeekOrigin.Begin);
string fileName = string.Format("MassAVRMSDataExport{0}.csv", DateTime.Now.ToString("yyyyMMddhhmmss"));
Response.ClearHeaders();
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
Response.AddHeader("Content-Length", stream.Length.ToString(CultureInfo.InvariantCulture));
StreamHelper.CopyStream(stream, Response.OutputStream);
Response.Flush();
Response.End();
}
}
Greg you need to add the following when working with IE Explorer
Response.ContentType = "application/download"
Try setting:
stream.Position = 0;
StreamHelper.CopyStream(stream, Response.OutputStream);

download multiple pdf

I am trying to download multiple pdf's as attachments in my asp.net application.I have created some templates and filling values using pdfstamper(itextsharp). I am able to fill the values but not able to download.
private void FillForm(string path, DataTable BridgeValues, DataTable Comments, DataTable Maintenance,string Newfilename)
{
try
{
string pdfTemplate = path;
string newFile = Newfilename;
string Pathser = "";
if (!System.IO.Directory.Exists(Server.MapPath(#"~/PDF/")))
{
System.IO.Directory.CreateDirectory(Server.MapPath(#"~/PDF/"));
}
if (Directory.Exists(Server.MapPath(#"~/PDF/")))
{
Pathser = Server.MapPath(#"~/PDF/" + Newfilename);
}
System.IO.MemoryStream mStream = new System.IO.MemoryStream();
// create a new PDF reader based on the PDF template document
PdfReader pdfReader = new PdfReader(pdfTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(Pathser, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
DataColumn dc = null;
for (int i = 0; i < BridgeValues.Columns.Count - 1; i++)
{
dc = BridgeValues.Columns[i];
pdfFormFields.SetField(dc.ColumnName.ToString(), BridgeValues.Rows[0][dc].ToString());
}
pdfStamper.FormFlattening = true;
// close the pdf
pdfStamper.Close();
////Response.ContentType = "application/octet-stream";
Response.ContentType = "application/pdf";
////Response.AddHeader("Content-Disposition", "attachment; filename=Report.pdf");
Response.AddHeader("Content-Disposition", "attachment; filename=" + Newfilename + "");
////Response.BinaryWrite(mStream.ToArray());
Response.TransmitFile(Server.MapPath(("~/PDF/"+ Newfilename)));
Response.Clear();
Response.End();
}
catch (System.Threading.ThreadAbortException lException)
{
// do nothing
}
}
First time I tried to create one pdf ,it worked but later when I tried to download multiple files it gave an execption.
Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.
I don't think you can download multiple files by making one request and returning a collection from the action. I would suggest that it you need to allow user to download multiple files you ZIP them and stream the archive down to the browser.
Here is an example of zipping multiple files: http://devpinoy.org/blogs/keithrull/archive/2008/01/25/how-to-create-zip-files-in-c-with-sharpziplib-ziplib.aspx

Modifying a PDF using iTextSharp

I have a HttpModule that intercepts requests for PDF documents and I would like to add a date to the PDF and stream back to the client.
My code so far is
context.Response.ClearContent();
using (MemoryStream ms = new MemoryStream())
{
PdfReader reader = new PdfReader(document.Url + "&a=1");
PdfStamper stamper = new PdfStamper(reader, ms);
// *** Modify PDF here
stamper.Close();
context.Response.ContentType = "application/pdf";
context.Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
context.Response.OutputStream.Flush();
context.Response.OutputStream.Close();
context.Response.Flush();
context.Response.End();
}
HttpContext.Current.ApplicationInstance.CompleteRequest();
The code above works fine, but as soon as I try to modify the PDF I get a PDF Reader error 'The file is damaged and cannot be repaired', for example
TextField textField = new TextField(stamper.Writer, new Rectangle(0, 1000, 90, 600), name);
textField.Font = FontFactory.GetFont(FontFactory.HELVETICA, DEFAULT_FONT_SIZE, Font.NORMAL).BaseFont;
textField.FontSize = DEFAULT_FONT_SIZE;
textField.Rotation = 90;
PdfFormField field = textField.GetTextField();
stamper.AddAnnotation(field, page);
Does anyone know how I can solve this issue?
You continue sending stuff after the pdf, add
context.Response.End();
after:
context.Response.Flush();
Now you will send only the pdf, instead of the whole page. This sometimes fixes this issue.
You are also reading the buffer twice:
context.Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
try to add
byte[] bytes = ms.ToArray();
and then
context.Response.OutputStream.BinaryWrite(bytes);

Categories

Resources