Biff MaGriff
Biff MaGriff

Reputation: 8231

How do I insert a table into a PDF document with iTextSharp?

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();
    }
}

Upvotes: 3

Views: 24427

Answers (2)

Maverik
Maverik

Reputation: 5671

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 :)

Upvotes: 2

Biff MaGriff
Biff MaGriff

Reputation: 8231

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();
    }
}

Upvotes: 0

Related Questions