views:

68

answers:

3

Hi people, 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!

A: 

Looking though the itextsharp code its possible that it doesn't always work well with multiple readers on the same content.

I suggest you try

page = copy.GetImportedPage(reader, i);

rather than create a new reader for each page you're trying to read.

UPDATE: I don't know if the helps but

I copied and pasted your code and I get a NullReferenceException but only on this line

 stamp.AlterContents();

Which is strange because that's after where you are getting it.+

When passing in bad contents in the List I was able to produce Missing PDF header, Trailer Not found etc., so I don't think its a difference in the content of p

I'm using version 5.0.4 with the source code version built in VS 2008. The client is vs 2010. Perhaps these account for the difference.

Conrad Frix
Thanks for your reply, but that didn't help, I edited the code so this is what i have right now:
valin077
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
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.
valin077
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
Conrad Frix
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
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!
valin077
A: 

Not sure if this will fix it for you, but try initializing GetImportedPage starting at page 1, not zero but usng int i = 1 in your for loop. Like this:

// loop over document pages 
//was (int i = 0; i < pages; i++) {
for (int i = 1; i < pages; i++) {
    page = copy.GetImportedPage(new PdfReader(p), i);
    stamp = copy.CreatePageStamp(page);
    PdfContentByte cb = stamp.GetUnderContent();
    cb.SaveState();
    stamp.AlterContents();
    copy.AddPage(page);
}
Jay Riggs
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
A: 

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

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

        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;

            //PdfCopy copy = new PdfCopy(doc, ms);
            //PdfCopy.PageStamp stamp;

            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);
                    //page = copy.GetImportedPage(reader, i);
                    //stamp = copy.CreatePageStamp(page);
                    //cb = stamp.GetUnderContent();
                    //cb.SaveState();
                    //stamp.AlterContents();
                    //copy.AddPage(page);
                }
            }

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

        return todos;
    }

Hope that helps!

valin077