3

I want to insert a table into my existing PDF document.

I was following a post about inserting an image into a PDF but I'm getting an null reference exception error when trying to add the table.

Here is my current code

public static byte[] InsertTable(byte[] pdf, DataTable dt, int pageNum, int x, int y, int columns, int rows, int[] columnWidths, float rowHeight)
{
    using (var inputPDF = new MemoryStream(pdf))
    using (var outputPDF = new MemoryStream())
    {
        var reader = new PdfReader(inputPDF);
        var stamper = new PdfStamper(reader, outputPDF);
        var pdfContentByte = stamper.GetOverContent(pageNum);


        Table t = new Table(columns, rows);
        t.SetWidths(columnWidths);

        foreach (DataRow dr in dt.Rows)
            foreach (object o in dr.ItemArray)
            {
                Cell c = new Cell();
                c.Add(new Chunk(o.ToString()));
                t.AddCell(c);
            }
        pdfContentByte.PdfDocument.Add(t);
        pdfContentByte.PdfDocument.Close();
        return outputPDF.ToArray();
    }
}
Biff MaGriff
  • 8,102
  • 9
  • 61
  • 98
  • Null reference exception on what: pdfContentByte, pdfContentByte.PdfDocument or the table? Could you post the exception (stack)? – Nimrod Feb 22 '11 at 19:31
  • @Nimrod The exception bubbles out of the `.Add()` call. – Biff MaGriff Feb 22 '11 at 20:03
  • put a breakpoint on the statement and see if PdFDocument of pdfContentByte is ok before Add is called (I'd imagine it is, but just to be sure) – Maverik Feb 22 '11 at 20:19
  • Yup, the actual objects themselves exist but there is a null reference bubbling out. Perhaps I should update my library. – Biff MaGriff Feb 22 '11 at 20:23

2 Answers2

2

Although the code seems ok, I'm a bit confused by your line

Table t = new Table(columns, rows);

Are you sure thats what you want and not PdfPTable. Everything else in your code seems to be using PdfPTable, and I haven't been able to find a plain Table in iTextSharp.

And coincidently enough, I'm working on pretty similar thing right now.

EDIT For Modified Code

I've cleaned up the fields that aren't being used anymore as well:

public static byte[] InsertTable(byte[] buffer, DataTable dt, int columns, float[] columnWidths)
    {
        using (MemoryStream inputPDF = new MemoryStream(buffer))
        using (MemoryStream outputPDF = new MemoryStream())
        {
            PdfReader reader = new PdfReader(inputPDF);
            iTextSharp.text.Document doc = new iTextSharp.text.Document();
            PdfWriter write = PdfWriter.GetInstance(doc, outputPDF);
            doc.Open();

            for (int i = 1; i <= reader.NumberOfPages; i++)
            {
                doc.NewPage();
                write.DirectContent.AddTemplate(write.GetImportedPage(reader, i), 1f, 0, 0, 1, 0, 0);
            }

            //adding my table
            PdfPTable t = new PdfPTable(columns);
            t.SetTotalWidth(columnWidths);

            foreach (DataRow dr in dt.Rows)
                foreach (object o in dr.ItemArray)
                {
                    PdfPCell c = new PdfPCell();
                    c.AddElement(new Chunk(o.ToString()));
                    t.AddCell(c);
                }

            doc.NewPage();

            doc.Add(t);
            doc.Close();
            write.Close();
            reader.Close();
            return outputPDF.ToArray();
        }
    }

Hope this solves your problem. I'm online for next six hours and will try to keep an eye on this until I head back home :)

Maverik
  • 5,619
  • 35
  • 48
  • The Table I am using is under `iTextSharp.Text.Table` – Biff MaGriff Feb 22 '11 at 20:04
  • I guess we're using different versions. I'm using the 5.0.6 release of iTextSharp dll and there is no Table in Text (iTextSharp.text) namespace. – Maverik Feb 22 '11 at 20:17
  • Haha, yeah I'm using version 4.1.6. I'm switching to the PdfTable class. I'll let you know how it goes. – Biff MaGriff Feb 22 '11 at 20:22
  • Thanks Maverik, I'm going to be revisiting this in a few days. Currently I'm out of town on another project. I want to overlay my table so I moved my table building code into the "newpage" loop. Now I just have to figure out how to position it exactly. Thanks again for the help! – Biff MaGriff Feb 23 '11 at 19:25
0

Ok, I updated to 5.0.6 And I got the table inserted. Right now everything is getting rendered on the first page though.

public static byte[] InsertTable(byte[] pdf, DataTable dt, int pageNum, float x, float y, int columns, int rows, float[] columnWidths, float rowHeight)
{
    using (var inputPDF = new MemoryStream(pdf))
    using (var outputPDF = new MemoryStream())
    {
        //loading existing
        var reader = new PdfReader(inputPDF);
        Document doc = new Document();
        PdfWriter write = PdfWriter.GetInstance(doc, outputPDF);
        doc.Open();
        PdfContentByte canvas = write.DirectContent;
        PdfImportedPage page;
        for (int i = 1; i <= reader.NumberOfPages; i++) {
            page = write.GetImportedPage(reader, i);
            canvas.AddTemplate(page, 1f, 0, 0, 1, 0, 0);
        }

        //adding my table
        PdfPTable t = new PdfPTable(columns);
        t.SetTotalWidth(columnWidths);

        foreach (DataRow dr in dt.Rows)
            foreach (object o in dr.ItemArray)
            {
                PdfPCell c = new PdfPCell();
                c.AddElement(new Chunk(o.ToString()));
                t.AddCell(c);
            }
        doc.Add(t);
        doc.Close();
        return outputPDF.ToArray();
    }
}
Biff MaGriff
  • 8,102
  • 9
  • 61
  • 98
  • Where do you wish the table to appear? At the end of existing document I'm guessing? – Maverik Feb 23 '11 at 09:35
  • Had my morning coffee and now I see what you mean! You're missing Doc.NewPage() (and its relevant DirectContent) so you end up writing on the same Content over and over and hence the result. I've modified your code and tested with my own app; seems to be working now. New code added to my original post. – Maverik Feb 23 '11 at 10:49
  • Actually I want to position it exactly over top an existing table. – Biff MaGriff Feb 23 '11 at 19:22