iTextSharp creation of a pdf from a list of byte arrays

50,394

Solution 1

I've figured it out, just so everbody can have the solution: here it is:

    public static byte[] concatAndAddContent(List<byte[]> pdf)
    {
        byte [] all;

        using(MemoryStream ms = new MemoryStream())
        {
            Document doc = new Document();

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

            doc.SetPageSize(PageSize.LETTER);
            doc.Open();
            PdfContentByte cb = writer.DirectContent;
            PdfImportedPage page;

            PdfReader reader;
            foreach (byte[] p in pdf)
            {
                reader = new PdfReader(p);
                int pages = reader.NumberOfPages;

                // loop over document pages
                for (int i = 1; i <= pages; i++)
                {
                    doc.SetPageSize(PageSize.LETTER);
                    doc.NewPage();
                    page = writer.GetImportedPage(reader, i);
                    cb.AddTemplate(page, 0, 0);
                }
            }

            doc.Close();
            all = ms.GetBuffer();
            ms.Flush();
            ms.Dispose();
        }

        return all;
    }

Hope that helps!

Solution 2

This works:

used iTextSharp-LGPL 4.1.6:

    public static byte[] ConcatenatePdfs(IEnumerable<byte[]> documents)
    {
        using (var ms = new MemoryStream())
        {
            var outputDocument = new Document();
            var writer = new PdfCopy(outputDocument, ms);
            outputDocument.Open();

            foreach (var doc in documents)
            {
                var reader = new PdfReader(doc);
                for (var i = 1; i <= reader.NumberOfPages; i++)
                {
                    writer.AddPage(writer.GetImportedPage(reader, i));
                }
                writer.FreeReader(reader);
                reader.Close();
            }

            writer.Close();
            outputDocument.Close();
            var allPagesContent = ms.GetBuffer();
            ms.Flush();

            return allPagesContent;
        }
    }

Solution 3

This solution works in iText 7.1.8:

It is based in previous answers and the new API Examples

    public static byte[] MergePDFs(List<byte[]> lPdfByteContent)
    {
        using (MemoryStream oMemoryStream = new MemoryStream())
        {
            using (PdfWriter oWriter = new PdfWriter(oMemoryStream))
            {
                oWriter.SetSmartMode(true);

                using (PdfDocument oMergedPdf = new PdfDocument(oWriter))
                {
                    PdfMerger oMerger = new PdfMerger(oMergedPdf, false, false);

                    for (int i = 0; i < lPdfByteContent.Count; i++)
                    {
                        PdfDocument oPdfAux = new PdfDocument(new PdfReader(new MemoryStream(lPdfByteContent[i])));
                        oMerger.SetCloseSourceDocuments(true).Merge(oPdfAux, 1, oPdfAux.GetNumberOfPages());
                    }
                }
            }
            return oMemoryStream.ToArray();
        }
    }
Share:
50,394
valin077
Author by

valin077

Updated on July 10, 2022

Comments

  • valin077
    valin077 almost 2 years

    I've got a list of byte[] which i'd like to concatenate into one byte[] which will be the final PDf.

    On the "page = copy.GetImportedPage(new PdfReader(p), i); " i'm getting an "object reference not set to an instance error.

    I've got no clue of what's going on, i've already checked every object and there's no null.

    Any ideas on this, or another piece of code that could make the trick?!

    I've got this method:

    EDIT

          public static byte[] concatAndAddContent(List<byte[]> pdf)
        {
            byte [] todos;
    
            using(MemoryStream ms = new MemoryStream())
            {
                Document doc = new Document();
                doc.Open();
    
                PdfCopy copy = new PdfCopy(doc, ms);
                PdfCopyFields copy2 = new PdfCopyFields(ms);
    
    
                PdfReader reader;
                foreach (byte[] p in pdf)
                {
                    reader = new PdfReader(p);
                    int pages = reader.NumberOfPages;
    
                    // loop over document pages
                    for (int i = 1; i < pages; i++)
                    {
                        PdfImportedPage page = copy.GetImportedPage(reader, i);
                        PdfCopy.PageStamp stamp = copy.CreatePageStamp(page);
                        PdfContentByte cb = stamp.GetUnderContent();
                        cb.SaveState();
                        stamp.AlterContents();
                        copy.AddPage(page);
                    }
                }
    
                doc.Close();
                todos = ms.GetBuffer();
                ms.Flush();
                ms.Dispose();
            }
    
            return todos;
        }
    

    Stack Trace:

    [NullReferenceException: Object reference not set to an instance of an object.]
       iTextSharp.text.pdf.PdfImportedPage..ctor(PdfReaderInstance readerInstance, PdfWriter writer, Int32 pageNumber) +45
       iTextSharp.text.pdf.PdfReaderInstance.GetImportedPage(Int32 pageNumber) +175
       iTextSharp.text.pdf.PdfCopy.GetImportedPage(PdfReader reader, Int32 pageNumber) +256
       SAM.Web.Classes.UtileriasReportes.concatAndAddContent(List`1 pdf) in \Classes\UtileriasReportes.cs:199
       SAM.Web.Classes.UtileriasReportes.ObtenReporteOdt(Int32 ordenTrabajoID, Boolean caratula, Boolean juntas, Boolean cortes, Boolean materiales, Boolean resumenMateriales) 
    
    in D:\MIMOSS\Desarrollo\SAM 2.0\Desarrollo\WebSolution\SAM.Web\Classes\UtileriasReportes.cs:168
       SAM.Web.Produccion.PopupImpresionOdt.btnImprimir_Click(Object sender, EventArgs e) in \PopupImpresionOdt.aspx.cs:44
       System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
       System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
       System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
       System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
       System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563
    

    thanks for your time!

  • valin077
    valin077 over 13 years
    Thanks for your reply, but that didn't help, I edited the code so this is what i have right now:
  • valin077
    valin077 over 13 years
    PdfReader reader; foreach (byte[] p in pdf) { reader = new PdfReader(p); int pages = reader.NumberOfPages; // loop over document pages for (int i = 0; i < pages;) { PdfImportedPage page = copy.GetImportedPage(reader, ++i);
  • valin077
    valin077 over 13 years
    actually thats correct, using the GetImportedPage(reader, 0) it returns an error, but starting the page at 1 keeps giving me the null reference exception. i'm lost here, can't understang why. Thanks, I really appreciate your help!
  • valin077
    valin077 over 13 years
    my bad, i actually modified the code changing the byte[] name from todos to all, and missed it, but thats not the problem. I'll edit the code and leave it just as I have it right now. Thanks for your help.
  • Conrad Frix
    Conrad Frix over 13 years
    I updated my answer to remove the bits about compile errors, but I honestly don't think it will help. Like I said I tried passing in goofy content to try and reproduce your issue but iTextSharp is pretty robust in the face of bad content
  • valin077
    valin077 over 13 years
    Well that might be the problem. I'm using version 4.1.2 in vs2010, i'll try and look up for the newest version and give it a try. Thanks for your help, i'll update on the results.
  • valin077
    valin077 over 13 years
    I've updated the iTextSharp version and got the NullReferenceException you are talking about in the stamp.alterContents(); I'll take a look on that thank you so much for your help! If i had more reputation i would vote you answer as useful, thanks again!
  • Daniel Brown
    Daniel Brown over 7 years
    You'r a legend! Thanks for coming back to share this nugget.
  • Developer
    Developer about 3 years
    Getting an error PDF header signature not found. can some one help