user1126775
user1126775

Reputation: 103

How to write and split a datatable on different pages using itextsharp?

first at all, here is my code:

                    string pdfTemplate = Application.StartupPath + "\\Templates\\Template Medico.pdf";
                    string newFile = Application.StartupPath + "\\Relatórios\\Relatório Médico_" + dataArquivo + ".pdf";

                    PdfReader pdfReader = new PdfReader(pdfTemplate);
                    PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create));

                    AcroFields pdfFormFields = pdfStamper.AcroFields;

                    // Form Filling
                    pdfFormFields.SetField("data", data);
                    pdfFormFields.SetField("medico_nome", campo);
                    pdfFormFields.SetField("numero_consultas", numeroConsultas);

                    // Table Building
                    int numColumns = ds.Tables[0].Columns.Count;
                    PdfPTable datatable = new PdfPTable(numColumns);
                    datatable.DefaultCell.Padding = 10;
                    datatable.WidthPercentage = 100; 
                    datatable.DefaultCell.HorizontalAlignment = Element.ALIGN_LEFT;
                    float[] columnWidths = { 80, 80, 80, 80, 80, 80, 80, 80, 80 };
                    datatable.SetWidths(columnWidths);
                    float[] totalWidth = { 80, 80, 80, 80, 80, 80, 80, 80, 80 };
                    datatable.SetTotalWidth(totalWidth);

                    // Table Header
                    for (int k = 0; k < ds.Tables[0].Columns.Count; k++)
                    {
                        Phrase collumname = new Phrase(ds.Tables[0].Columns[k].ColumnName, FontFactory.GetFont("Verdana", 9));
                        datatable.AddCell(collumname);
                    }
                    // Lines and Columns
                    if (ds.Tables[0].Rows.Count <= 9) // less than 9 rows = no problem, no new pages and table spliting needed
                    {
                        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                        {
                            for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
                            {
                                datatable.DefaultCell.BackgroundColor = iTextSharp.text.BaseColor.WHITE;
                                datatable.DefaultCell.HorizontalAlignment = iTextSharp.text.Element.ALIGN_LEFT;
                                Phrase phrase = new Phrase(ds.Tables[0].Rows[i][j].ToString(), FontFactory.GetFont("Verdana", 9));
                                datatable.AddCell(phrase);
                            }
                        }
                        // Write down the table on page 2
                        PdfContentByte content = pdfStamper.GetUnderContent(2);
                        datatable.WriteSelectedRows(0, -1, 70.0f, 495.0f, content);
                    }
                    else
                    {
                        int newPage = 3;
                        int currentPage = 2;
                        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                        {
                            for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
                            {
                                datatable.DefaultCell.BackgroundColor = iTextSharp.text.BaseColor.WHITE;
                                datatable.DefaultCell.HorizontalAlignment = iTextSharp.text.Element.ALIGN_LEFT;
                                Phrase phrase = new Phrase(ds.Tables[0].Rows[i][j].ToString(), FontFactory.GetFont("Verdana", 9));
                                datatable.AddCell(phrase);
                            }
                            if (i > 0 && i % 9 == 0)
                            {   //How do i print the table ONLY every 9 iterations? (9 iterations = 9 rows)
                                PdfContentByte content = pdfStamper.GetUnderContent(currentPage);
                                // Or how do i make a loop using the rowStart and rowEnd arguments of the
                                // WriteSelectedRows function in order to write only a set of 9 rows for each page?
                                datatable.WriteSelectedRows(0, -1, 70.0f, 495.0f, content);
                                pdfStamper.InsertPage(newPage, pdfReader.GetPageSize(2));
                                newPage++;
                                currentPage++;
                            }
                        }
                    }

The code is well commented with the main issues i'm having at the moment, but the real bigger one, as described on the thread title is to somehow "split" or "control" the loop/iteration through the rows and columns to match the page, jump to the other page, and keep writing the table.

Any help will be apreciated.

Upvotes: 1

Views: 4366

Answers (2)

Gigi Sapun
Gigi Sapun

Reputation: 11

You can do it easier by fully using WriteSelectedRows

int pageRows=0;    
while (pageRows<datatable.Rows.Count+8)
      {
         content.BeginText();
         table.WriteSelectedRows(pageRows, pageRows+9, 20, 550, cb);
         pageRows = pageRows + 9;
         content.EndText();
         document.NewPage();
       }

You write 9 rows at a time, and then you call for a new page.

Upvotes: 1

user1126775
user1126775

Reputation: 103

Did it guys, took me 2 days and lots of cooffe but i did it, here is the code:

                else
                {
                    int newPageNumber = 3;
                    int currentPage = 2;
                    int lastLinePrinted = 0;
                    int maxLine = 9;
                    bool lastPage = false;
                    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                    {
                        for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
                        {
                            datatable.DefaultCell.BackgroundColor = iTextSharp.text.BaseColor.WHITE;
                            datatable.DefaultCell.HorizontalAlignment = iTextSharp.text.Element.ALIGN_LEFT;
                            Phrase phrase = new Phrase(ds.Tables[0].Rows[i][j].ToString(), FontFactory.GetFont("Verdana", 9));
                            datatable.AddCell(phrase);
                        }
                        // must decrement the ds.Tables[0].Rows.Count here, 
                        // otherwise it'll never enter the code below, we'll
                        // increment it back when we reach the last page
                        if ((i > 0 && i % 9 == 0) || i == ds.Tables[0].Rows.Count - 1)
                        {
                            PdfContentByte content = pdfStamper.GetUnderContent(currentPage);
                            datatable.WriteSelectedRows(lastLinePrinted, maxLine, 70.0f, 495.0f, content);
                            if (!lastPage)
                            {
                                pdfStamper.InsertPage(newPage, pdfReader.GetPageSize(2));
                                newPage++;
                                currentPage++;
                                lastLinePrinted = maxLine;
                                maxLine += 9;
                            }
                            if (maxLine > ds.Tables[0].Rows.Count)
                            {
                                maxLine = ds.Tables[0].Rows.Count+1;
                                lastPage = true;
                            }
                        }
                    }
                }

Hope it helps a lot more people :D

Upvotes: 3

Related Questions