1

I have a PDF that has a plugin control on one page. I need to merge it with another pdf but when I do, the plugin is redendered as a blank rectangle. Is there a way to merge and preserve the plugin control? If important, the plugin is a Dessault Systemes 3D Via Composer Player control as installed from http://www.3ds.com/products/3dvia/3dvia-composer/resource-center/

The code I'm using is simple writer getinstance, contentbyte directcontent, getimportedpage, addtemplate. Nothing fancy.

FileStream docStream = new FileStream(@"C:\Temp\Merged.pdf", FileMode.Create);
            Document newDocument = new Document(PageSize.A4.Rotate());
            PdfWriter pdfWriter = PdfWriter.GetInstance(newDocument, docStream);
        try
        {
            newDocument.Open();
            PdfContentByte pdfContentByte = pdfWriter.DirectContent;

            newDocument.NewPage();
            PdfReader mainPage = new PdfReader(@"C:\Temp\PageWithPlugin.pdf");
            PdfImportedPage importedPage1 = pdfWriter.GetImportedPage(mainPage, 1);
            pdfContentByte.AddTemplate(importedPage1, 0, 0);
            mainPage.Close();

            PdfReader smgPages = new PdfReader(@"C:\Temp\MorePages.pdf");
            for (int page = 1; page <= smgPage.NumberOfPages; page++)
            {
                newDocument.NewPage();
                PdfImportedPage importedPage = pdfWriter.GetImportedPage(smgPages, page);
                pdfContentByte.AddTemplate(importedPage, 0, 0);
            }
            smgPages.Close();

            }
        finally
        {
            docStream.Flush();
            if (newDocument != null)
                newDocument.Close();
            docStream.Close();
        }
JeffLit
  • 13
  • 1
  • 3

2 Answers2

1

Give this a try.

List<byte[]> fileList = new List<byte[]>();

using (FileStream fileSteam = File.OpenRead((@"C:\Temp\PageWithPlugin.pdf")))
{
     Byte[] byteArray = new byte[fileSteam.Length];
     fileSteam.Read(byteArray, 0, byteArray.Length);

     fileList.Add(byteArray);
}

using (FileStream fileSteam = File.OpenRead((@"C:\Temp\MorePages.pdf")))
{
     Byte[] byteArray = new byte[fileSteam.Length];
     fileSteam.Read(byteArray, 0, byteArray.Length);

     fileList.Add(byteArray);
}

using(MemoryStream msOutput = new MemoryStream())
{
     PdfReader pdfFile = new PdfReader(fileList[0]);
     Document doc = new Document();
     PdfWriter pCopy = new PdfSmartCopy(doc, msOutput);

     doc.Open();

     for (int k = 0; k < fileList.Count; k++)
     {
         for (int i = 1; i < pdfFile.NumberOfPages + 1; i++)
         {
             pdfFile = new PdfReader(fileList[k]);
             ((PdfSmartCopy)pCopy).AddPage(pCopy.GetImportedPage(pdfFile, i));
             pCopy.FreeReader(pdfFile);
         }
     }

     pdfFile.Close();
     pCopy.Close();
     doc.Close();
     fileList.Clear();

     byte[] form = msOutput.ToArray();

     using (FileStream fileSteam = new FileStream(@"C:\Temp\Merged.pdf", FileMode.Create))
     {
          fileStream.Write(form, 0, form.Length);
     }
}
Jonathan
  • 1,719
  • 1
  • 15
  • 19
  • 1
    Either `PdfCopy` or `PdfSmartCopy` will work. `PdfSmartCopy` compares all the streams imported into the PDF to make sure there are no duplicates. Overhead, but it can lead to **much** smaller PDFs in some cases. – Mark Storer Jul 19 '11 at 22:00
  • That worked perfectly. Thanks very much for the timely response. – JeffLit Jul 19 '11 at 22:47
  • Not to look a gift horse in the mouth but... In case anyone else uses the solution, there is a small problem with the k loop. The numberofpages would be off by one document after the zeroth one and the pdfReader keeps getting freed and reread for every page, which isn't necessary. I think this is an improvement for that part of the code: – JeffLit Jul 20 '11 at 15:21
  • One other question... MorePages.pdf has Chapters. When opened alone the TOC can be viewed but no TOC in Merged.pdf. Is there any way to preserve the Chapters/TOC when merging? – JeffLit Jul 20 '11 at 17:57
  • @JeffLit That's a good question I'm not familiar with how chapters are handled in iTextSharp. As far as the error you see in the k loop I have not experienced an issue with it. The k loop iterates through the file list which is a 0-based array and when it reaches the last document the loop proceeds, iterating k again which then is equal to the list count and the loop terminates. I will however give the PdfReader and FeeReader moved outside loop i a try. Thanks and good luck. – Jonathan Jul 20 '11 at 18:53
0

Not to look a gift horse in the mouth but... In case anyone else uses the solution, there is a small problem with the k loop. The numberofpages would be off by one document after the zeroth one and the pdfReader keeps getting freed and reread for every page, which isn't necessary. I think this is an improvement for that part of the code:

using (MemoryStream msOutput = new MemoryStream())
            {
                Document doc = new Document();
                PdfWriter pCopy = new PdfCopy(doc, msOutput);
                doc.Open();
                for (int k = 0; k < fileList.Count; k++)
                {
                    PdfReader pdfFile = new PdfReader(fileList[k]);                        
                    for (int i = 1; i < pdfFile.NumberOfPages + 1; i++)
                    {
                        ((PdfCopy)pCopy).AddPage(pCopy.GetImportedPage(pdfFile, i));
                    }
                    pCopy.FreeReader(pdfFile);
                    pdfFile.Close();
                }
                pCopy.Close();
                doc.Close();
                fileList.Clear();
JeffLit
  • 13
  • 1
  • 3