0

I try to use the code I found here http://web.archive.org/web/20111012184438/http://alex.buayacorp.com/merge-pdf-files-with-itext-and-net.html to merge 2 or more PDF files into one.

I want to achieve that the output is returned as a stream and saved on client side. I tried to modify the code but without success. The code tries to save the output on the server which then causes an Unauthorized Access Exception. Anyone has the right clue?


private void MergePDFs()
{
    DataSourceSelectArguments args = new DataSourceSelectArguments();
    DataView view = (DataView)SqlDataSource1.Select(args);

    DataTable table = view.ToTable();
    List<PdfReader> readerList = new List<PdfReader>();

    foreach (DataRow myRow in table.Rows)
    {
        PdfReader pdfReader = new PdfReader(Convert.ToString(myRow[0]));
        readerList.Add(pdfReader);
    }

    Document document = new Document();
    PdfCopy copy = new PdfCopy(document, Response.OutputStream);
    document.Open();

    foreach (PdfReader reader in readerList)
    {
        for (int i = 1; i <= reader.NumberOfPages; i++)
        {
            copy.AddPage(copy.GetImportedPage(reader, i));
        }
    }

    document.Close();
    Response.AppendHeader("content-disposition", "inline; filename=OutPut.pdf");
    Response.ContentType = "application/pdf";
}
Barnabeck
  • 459
  • 1
  • 6
  • 26
  • *I tried to modify the code* - Have you tried replacing the `FileStream` by a response stream (or a `MemoryStream` the content of which you eventually copy to the response stream)?` That been asked, the code you found is an example for how usually *not* to merge PDFs. Use code working with `PdfCopy`. – mkl Oct 29 '15 at 16:56
  • I tried both response stream and memory stream, but as a newbie I didn't succeed. It confuses me what you say about the code, not being meant for merging PDF. It seems to be exactly for that purpose!? – Barnabeck Oct 29 '15 at 17:05
  • *It seems to be exactly for that purpose!?* - yes, but it is done the wrong way. Have a look at [this answer](http://stackoverflow.com/a/15945467/1729265) for details. – mkl Oct 29 '15 at 23:19

1 Answers1

0

It seems that you are using an OutputStream that writes the PDF bytes as a file on the server's disk. That is typically something you don't want in a web application. In a web application you want to write the bytes to the Response object as is described in the answer to iTextSharp generated PDF: How to send the pdf to the client and add a prompt?

Common sense will tell you that it's best to write the bytes straight the the OutputStream of the Response, but experience has taught us that not all browsers handle those bytes correctly. It's a good idea to write the PDF to a MemoryStream first (as explained in Create PDF in memory instead of physical file). Once you have the bytes in memory, then you can flush the bytes to the Response object after setting the right HTTP headers (especially the ContentLength is important for some browser).

It is obvious that you can't just write the bytes to the client without consent of the user, for instance because

  1. This would be a security hazard. Browsers shouldn't allow servers to write whatever content to the end user's disk.
  2. You have no idea of the organization of the file system of the end user (not every computer has a C: drive).

If you want the end user to save the PDF, you should use the following HTTP header:

Response.AddHeader("Content-Disposition", "attachment; filename=yourfile.pdf");

Want more info? Read How To Write Binary Files to the Browser Using ASP.NET and Visual C# .NET

An extra word of advice: please do me a favor and don't use bad iTextSharp examples. Merging PDFs is done with PdfCopy, NOT with PdfWriter. Download the free ebook The Best iText Questions on StackOverflow and you'll save plenty of time (1.) searching for answers and (2.) avoiding bad answers.

Community
  • 1
  • 1
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Feels like asking a question on Excel and Mr.Gates is answering himself! You're pretty active here - great! It took me a while to understand these examples. Not being too deep into it, I found it confusing that in the examples you are using other references than the ones I do - but I guess this is just due to my lack of knowledge. In the end I succeeded to make it work. The code is posted above. The problem I'm facing now is that I get a 'System.OutOfMemoryException' error, while I merge around 300 PDF's. I read I could write to the FileStream to reduce memory impact, but stumble over syntax – Barnabeck Oct 31 '15 at 12:04
  • You should make sure that you release some memory while performing your operation. For instance: I never see you doing `reader.Close()` anywhere. – Bruno Lowagie Oct 31 '15 at 17:09