iTextSharp generated PDF: How to send the pdf to t

2019-01-09 08:14发布

问题:

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

回答1:

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();


回答2:

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");


回答3:

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.



回答4:

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.



回答5:

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.