2

I'm writing a simple asp.net that will the user to download an object list as a PDF-document. When clicking the button "get pdf" the client browser should ask the user where they wish to save the file. And that's it. Pretty straight forward.

I've found several guides explaining how to generate a PDF from a datatable, but all of these seem to require you to save the pdf to some sort of temp file, storing it locally in the process.

PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("c://sample.pdf", FileMode.Create));

Is this really necessary to save the file locally and then pass it on the user, who can then choose to save the file again? Am I miss something here? Is there any way to generate the PDF on the file and then pass it on to the client browser?

EDIT:

To specify, what I'm talking about here is probably to send a stream directly to the client browser, the file being generated on the fly completely. No local storage until the user gets the "do you want to download this file" prompt.

user1531921
  • 1,372
  • 4
  • 18
  • 36

3 Answers3

5

If using iText (as you seem to be), this function call will take any sort of stream, e.g. the following will return a byte array that you can then stream to your client, without writing to disk:

using (MemoryStream ms = new MemoryStream())
{
    Document doc = new Document(PageSize.A4, 50, 50, 15, 15);

    PdfWriter writer = PdfWriter.GetInstance(doc, ms);

    //You need to actually write something to the document here...

    return ms.ToArray();
}
Paddy
  • 33,309
  • 15
  • 79
  • 114
3

The question is confusing as it is not clear what you mean by "locally".

Usually when you create a PDF on a server ("remotely"), you do not need to store the PDF on the file system of the server. You just create the PDF in memory and pass the bytes to the Response.OutputStream as is done in many other examples on StackOverflow.

The bytes are send to a client, where they are stored "locally" on the disk of the end user. The end user may not notice that the file is stored locally because it is stored in a temporary directory. Why is it stored locally? Because a PDF viewer needs the file on disk. A PDF viewer starts reading the file at the end. That's where the Cross-reference table is. The Cross-reference table contains byte offsets of every object in the PDF. A PDF viewer needs random access to a file to use these objects. See also Disable save button in Adobe PDF reader and hide menu bar in IE window

Community
  • 1
  • 1
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
0

Instead of saving the document to a file, you need to save it to the Response.OutputStream. You also should take care not to write anything to the browser before writing the PDF content. You should also set the response stream's content type to PDF mime type. To be user-friendly, you should add a header specifying the name of the PDF file. This will ensure that browser brings up the file save dialog box.

Response.Clear();
// Tell server to cache output until asked to flush
Response.BufferOutput = true;
// Set the mime type - tells the browser that a
// PDF document is on the way
Response.ContentType = "application/pdf";
// Give the document a name
Response.AddHeader(
    "content-disposition",
    "attachment; filename=pdf_doc.pdf");

Then write your PDF to the response stream, as Paddy has given. I don't think you need to change the memory steam to an array. I think you should be able to directly write the memorystream to response.OutputStream.

gn1
  • 526
  • 2
  • 5