Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iTextSharp creation of a pdf from a list of byte arrays

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!

like image 805
valin077 Avatar asked Oct 18 '10 17:10

valin077


3 Answers

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!

like image 93
valin077 Avatar answered Nov 09 '22 06:11

valin077


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;
        }
    }
like image 26
Nina Avatar answered Nov 09 '22 06:11

Nina


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();
        }
    }
like image 2
Andre Noivo Avatar answered Nov 09 '22 05:11

Andre Noivo