Table in iTextSharp is not page breaking as desire

2019-08-07 04:44发布

问题:

Problem

The header is on the first page by itself. If my body has too many people in it for photos, it will print on the second page. Please see below for a graphical description of my problem:

Now, please read below for some code. Please consider the following as pseudo code (because the whole code is too long), but it is very close to the code I am trying to fix.

Code

Header

   System.IO.FileInfo tempFileInfo
                    = new System.IO.FileInfo(System.IO.Path.GetTempFileName());

                tempFileInfo.MoveTo(tempFileInfo.FullName + ".pdf");

                Document document = new Document(PageSize._11X17);
                PdfWriter.GetInstance(document, new System.IO.FileStream(tempFileInfo.FullName, System.IO.FileMode.Create));
                document.AddTitle("Sample ");
                document.Open();
                document.SetMargins(0.5f, 0.5f, 0.5f, 0.5f);
                PdfPTable pdfPTableMain = new PdfPTable(1);    // 1 columns

                //Page Title
                iTextSharp.text.Font titleFont = iTextSharp.text.FontFactory.GetFont("Arial", 20, iTextSharp.text.Font.BOLD);
                iTextSharp.text.Paragraph titleParagraph = new Paragraph(terminalName + "\n\n"+ "Authorized Personnel", titleFont);
                PdfPCell cellTitle = new PdfPCell(titleParagraph);
                cellTitle.BorderColor = BaseColor.WHITE;
                cellTitle.NoWrap = true;
                cellTitle.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
                cellTitle.PaddingBottom = 10;
                pdfPTableMain.AddCell(cellTitle);

Body

PdfPTable pdfPTableList = new PdfPTable(6);
SqlConnection sqlConnection= Sample.Library.DB_Connection.OpenDatabase();

foreach (DataRow row in personDataSet.Tables[0].Rows)
{

      PdfPTable pdfPTablePhoto = new PdfPTable(1);

      iTextSharp.text.Image image =  
      iTextSharp.text.Image.GetInstance(GetPersonPhoto(personId),System.Drawing.Imaging.ImageFormat.Png);

       PdfPCell cellFullName = new PdfPCell(new Paragraph(fullName, fullnameFont));
       cellFullName.BorderColor = BaseColor.WHITE;
       cellFullName.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
       pdfPTablePhoto.AddCell(cellFullName);

       pdfPTableList.AddCell(pdfPTablePhoto);

}
pdfPTableList.CompleteRow();
pdfPTableMain.AddCell(pdfPTableList);

Footer

iTextSharp.text.Font footerFont1 = iTextSharp.text.FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.BOLD); 
            iTextSharp.text.Paragraph footerParagraph1 = new Paragraph(
                "POSTER GENERATED: " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString(), footerFont1);
            PdfPCell cellFooter1 = new PdfPCell(footerParagraph1);
            cellFooter1.BorderColor = BaseColor.WHITE;
            cellFooter.DisableBorderSide(Left);
            cellFooter.DisableBorderSide(Right);
            cellFooter.DisableBorderSide(Bottom);
            cellFooter.DisableBorderSide(Top);
            cellFooter1.NoWrap = true;
            cellFooter1.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
            cellFooter1.PaddingBottom = 5;
            pdfPTableMain.AddCell(cellFooter1);



            pdfPTableMain.KeepTogether = true;
            document.Add(pdfPTableMain);
            document.Close();

Code Wrap Up

It can be though as creating three objects cell1, cell2, and cell2 to a table.

table.Add(cell1);
table.Add(cell2);
table.Add(cell3);

Attempts

  • Using the syntax pdfPTableMain.KeepTogether = true
  • Using skipFirstHeader(true)
  • Should I define it as one table1.add(table2), where table2 contains 3 cells? (Update: I tried this. It did not work).

What I think is happening is that if my cell2 becomes too large, it just puts it on another page. The way I think about it is that I have 3 rows and the 2nd is too big to fit (so it puts it on another page). I'm not an expert on itext or itextsharp, and would deeply appreciate any assistance. I've tried a few other things, but that seemed to only make it worse. I humbly reach out to more experienced individuals and ask for assistance.

回答1:

The question you linked to is correct but worded a little weird in that it says that the PdfPTable class doesn't support column and row spans, which is true. However the PdfPCell class is what actually supports the Colspan which is what you need.

Below is a sample that creates 20 PDFs in a folder on your desktop. The first file has just 1 photo, the second has 2 and so on, just to show various possible iterations. You'll need one photo on your desktop called "photo.jpg" for it to work. See the comments in the code for more details.

//Just a sample photo
var photoPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "photo.jpg");

//Folder to export to
var exportFolder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Table Test");

//Create our export folder if it doesn't exist already
System.IO.Directory.CreateDirectory(exportFolder);

//We're going to make 20 different files to show off 20 different
//possible counts of people, each file will be named test_{count}.pdf
var exportFilePathFormat = System.IO.Path.Combine(exportFolder, "test_{0}.pdf");

//Do the PDF creation steps 20 times
for (var i = 1; i <= 20; i++) {

    //Get our specific file name for this loop
    var thisFile = string.Format(exportFilePathFormat, i);

    //Standard iTextSharp bootstrapping, nothing special here
    using (var fs = new FileStream(thisFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
        using (var doc = new Document()) {
            using (var writer = PdfWriter.GetInstance(doc, fs)) {

                //Open the document for writing
                doc.Open();

                //Create a two column table
                var t = new PdfPTable(2);

                //Create our header cell
                var headerCell = new PdfPCell(new Phrase("This is my header"));

                //Span it two columns
                headerCell.Colspan = 2;

                //Add it to the document
                t.AddCell(headerCell);

                //Create between 1 and 20 image cells
                for (var j = 1; j <= i; j++) {
                    t.AddCell(iTextSharp.text.Image.GetInstance(photoPath));
                }

                //Just in case we have an odd number of images, complete the row
                t.CompleteRow();

                //Footer is same as header
                var footerCell = new PdfPCell(new Phrase("This is my footer"));
                footerCell.Colspan = 2;
                t.AddCell(footerCell);

                //Add the table to the document
                doc.Add(t);

                doc.Close();
            }
        }
    }
}