1

I've developed a solution on my development machine where it:

  1. Opens PDFs for a file path server side via C#
  2. Merges them together
  3. Does a Response.BinaryWrite to push to a browser the merged PDF

Works great on local DEV. When pushed to server, it gets some 'binary gibberish' in the browser window.

Adobe or Foxit Reader is NOT installed on the server, however it is installed on my local dev machine. My understanding is that iTextSharp allowed you to not need PDF Readers installed at all, but does it? Or maybe this is an IIS thing where .pdf is not listed as a filetype...

Here is some sample code:

 // First set up the response and let the browser know a PDF is coming
            context.Response.Buffer = true;
            context.Response.ContentType = "application/pdf";
            context.Response.AddHeader("Content-Disposition", "inline");

            List<string> PDFs = new List<string>();
            PDFs.Add(@"c:\users\shane\documents\visual studio 2010\Projects\PDFMultiPrintTester\PDFMultiPrintTester\TEST1.pdf");
            PDFs.Add(@"c:\users\shane\documents\visual studio 2010\Projects\PDFMultiPrintTester\PDFMultiPrintTester\TEST2.pdf");
            PDFs.Add(@"c:\users\shane\documents\visual studio 2010\Projects\PDFMultiPrintTester\PDFMultiPrintTester\TEST3.pdf");

            // Second, some setup stuff
            System.IO.MemoryStream MemStream = new System.IO.MemoryStream();
            iTextSharp.text.Document doc = new iTextSharp.text.Document();
            iTextSharp.text.pdf.PdfReader reader = default(iTextSharp.text.pdf.PdfReader);
            int numberOfPages = 0;
            int currentPageNumber = 0;
            iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, MemStream);
            doc.Open();
            iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
            iTextSharp.text.pdf.PdfImportedPage page = default(iTextSharp.text.pdf.PdfImportedPage);
            int rotation = 0;

            foreach (string f in PDFs)
            {
                // Third, append all the PDFs--THIS IS THE MAGIC PART
                byte[] sqlbytes = null;
                sqlbytes = ReadFile(f);
                reader = new iTextSharp.text.pdf.PdfReader(sqlbytes);
                numberOfPages = reader.NumberOfPages;
                currentPageNumber = 0;

                while ((currentPageNumber < numberOfPages))
                {
                    currentPageNumber += 1;
                    doc.SetPageSize(PageSize.LETTER);
                    doc.NewPage();
                    page = writer.GetImportedPage(reader, currentPageNumber);
                    rotation = reader.GetPageRotation(currentPageNumber);
                    if ((rotation == 90) | (rotation == 270))
                    {
                        cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(currentPageNumber).Height);
                    }
                    else
                    {
                        cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
                    }
                }
            }

            // Finally Spit the stream out
            if (MemStream == null)
            {
                context.Response.Write("No Data is available for output");
            }
            else
            {
                doc.Close();
                context.Response.BinaryWrite(MemStream.GetBuffer());
                context.Response.End();
                MemStream.Close();
            }
        }
    }

    public static byte[] ReadFile(string filePath)
    {
        byte[] buffer;
        FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        try
        {
            int length = (int)fileStream.Length;  // get file length
            buffer = new byte[length];            // create buffer
            int count;                            // actual number of bytes read
            int sum = 0;                          // total number of bytes read

            // read until Read method returns 0 (end of the stream has been reached)
            while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
                sum += count;  // sum is a buffer offset for next reading
        }
        finally
        {
            fileStream.Close();
        }
        return buffer;
    }
Shane
  • 3,897
  • 7
  • 41
  • 61

3 Answers3

1

My understanding is that iTextSharp allowed you to not need PDF Readers installed at all, but does it?

iTextSharp is used to generate PDF files. It has nothing to do with the way those files are browsed. If you don't have a PDF reader installed on the client machine that is browsing the application streaming this PDF file in the response don't expect to get anything other than gibberish on this client machine.

Unfortunately you haven't shown the code that is used to generate this PDF file on the server so it's difficult to say whether the problem might be somehow related to it. The important thing is to set the ContentType of the response to application/pdf and send a valid PDF file to the response. The way this response is interpreted on the client will greatly depend on the browser being used and the different plugins and PDF readers installed on this client machine.

Darin Dimitrov
  • 960,118
  • 257
  • 3,196
  • 2,876
  • Yes, this assumes that a user with a browser does have pdf installed, its just a matter whether it needs to be installed on the server that is generating the PDF. I added code sample above. And yes, I'm changing the content type: context.Response.ContentType = "application/pdf"; – Shane Feb 28 '12 at 20:30
  • 1
    @Shane, no, you don't need anything installed on the server. iTextSharp has no dependencies with PDF readers whatsoever. – Darin Dimitrov Feb 28 '12 at 20:39
  • That was my understanding as well. Thanks. – Shane Feb 28 '12 at 20:45
0

You may need to set the Response.ContentType to application/pdf. See related SO post.

When you render Content-Disposition: inline it uses Adobe Plugin - "Adobe PDF Link Helper" (or FoxIt Reader) in IE. Since you probably don't have this ActiveX plugin on your server (AcroIEHelperShim.dll), it will just render the byte content inline as text/html since it doesn't have an inline interpreter.

Community
  • 1
  • 1
SliverNinja - MSFT
  • 29,007
  • 10
  • 98
  • 161
  • So what are you suggesting the solution is? – Shane Feb 28 '12 at 21:07
  • @Shane - you need a PDF interpreter such as Adobe Reader or FoxIt Reader installed on the server if you don't want to see the gibberish. `iTextSharp` is not an inline browser PDF renderer. – SliverNinja - MSFT Feb 28 '12 at 22:41
  • 1
    Actually, you don't need PDF installed on server I discovered. I finally got it to work by adding the MIME type of .pdf to IIS. It was not there. – Shane Feb 29 '12 at 15:14
0

Finally figured it out. You don't need Adobe PDF reader or Foxit Reader installed on the server. You only need iTextReader installed on the server (by installed I mean the assembly exists within your solution). The thing you do need is the MIME Type in IIS. We had to add that MIME type and it worked right away after that. Funny thing is that even with that, Chrome was able to figure it out and render it properly. I'm assuming that IIS puts the proper headers in place that associate with that MIME Type and that was not happening. IE8 couldn't figure it out.

Shane
  • 3,897
  • 7
  • 41
  • 61