views:

1296

answers:

2

I have an issue where I have a table (PdfPTable) that may extend past the length of the page. I have tried looking up how to "split" a table onto more than one page but iTextSharp is pretty poorly documented in this area. Does anyone know how to do this without choosing an arbitrary Y position on the page and telling it to split if it's there?

I looked into the SplitLate and SplitRows properties, but there's no documentation on what these do. EDIT They do nothing.

Thanks!

EDIT

I'm looking to cut the table in half widthwise as the table will always fit the width of the page. This is to say that I want the rows that don't fit vertically to extend to the next page below it.

EDIT2

Here's some code:

Public Sub BuildPrintableDocument
    Dim doc As New Document(PageSize.LETTER, 0, 0, 0, BOTTOM_MARGIN)
    Dim writer As PdfWriter = PdfWriter.GetInstance(doc, _
        New FileStream("invoice.pdf", FileMode.Create)

    Dim footer As New HeaderFooter(New Phrase("www.columbussupply.com", _
        footerFont), False)
    footer.Border = Rectangle.NO_BORDER
    footer.Alignment = HeaderFooter.ALIGN_CENTER
    doc.Footer = footer

    doc.Open()

....

Dim items As PdfPTable = NewItemTable()
Dim count As Integer = 0
    For Each oi As OrderItem In TheInvoice.Items
        If oi.Status <> OrderItem.OrderItemStatus.Cancelled Then
            Dim qty As New PdfPCell(New Phrase(oi.Quantity, mainFont))
            qty.HorizontalAlignment = Element.ALIGN_CENTER
            qty.Padding = ITEMS_PADDING

            '...instantiate 3 other cells here (removed for repetitiveness)'

            items.AddCell(qty)
            items.AddCell(desc)
            items.AddCell(price)
            items.AddCell(total)
        End If
    Next

    items.WriteSelectedRows(0, -1, LEFT_MARGIN, GetItemsStartY, _
        writer.DirectContent)
End Sub


Protected Function NewItemTable() As PdfPTable
    Dim items As PdfPTable = New PdfPTable(4)
    Dim headers() As String = {"QTY", "DESCRIPTION", "PRICE", "TOTAL"}

    For Each s As String In headers
        Dim cell As New PdfPCell(New Phrase(s, mainFont))
        cell.HorizontalAlignment = Element.ALIGN_CENTER
        items.AddCell(cell)
    Next

    items.TotalWidth = ITEMS_TOTAL_WIDTH
    items.SetWidths(New Single() {QTY_COL_WIDTH, DESC_COL_WIDTH, _ 
        PRICE_COL_WIDTH, TOTALS_COL_WIDTH})
    Return items
End Function
+1  A: 

When I was working with tables in iTextSharp, I found this resource useful:

iTextSharp Tutorial - Chapter 5: Tables

See the section entitled 'Large tables'. The tutorial includes a sample; I hope you haven't seen this before.

I don't recall splitting tables across pages being an issue. A problem I did have though was I wanted individual rows to be able to span pages. For this, I set the SplitLate property of my PdfPTable to false.

Edit
I checked through your code and compared it to mine. The big difference I saw was that I'm not adding my PdfPTable to my Document using the PdfPTable.WriteSelectedRows() method. Instead I call the Document's Add() method, passing in my PdfPTable with all the cells set. (BTW we load our PdfPCells in a similar manner.) I wonder if a PdfPTable written to a Document via WriteSelectedRows() is causing your problem.

You can also see if your code works if you don't add the HeaderFooter.

Jay Riggs
not working :\
Jason
is there some special place you have to put that in the process? like after you write the rows, before, where?
Jason
Sorry Jason, I misunderstood your question. I did edit my resonse which I hope helps.
Jay Riggs
thanks for the edit... yeah i have been through that tutorial 100x and to no avail. That chapter talks about using simple tables, and I need to use the PdfPTable so that I can absolutely position it. Right now the table I have just runs right off the edge of the page, which sucks.... :\
Jason
Have you set the margins of your document?
Jay Riggs
yep: `Dim doc As New Document(PageSize.LETTER, 0, 0, 0, BOTTOM_MARGIN)` where `BOTTOM_MARGIN` is 36
Jason
i've updated my question to include relevant code
Jason
I have an edit - I wonder if the method you're using to add the PdfPTable to your Document is causing your problem.
Jay Riggs
hrm... well, at this point i guess it's moot. i decided to artificially cut the table at 10 products and just make a new page :\ it's not the best solution, but thinking about it now, if i didn't, i could potentially have half of my totals table on one page and the rest on an empty sheet, which would suck. thanks anyways for your help, maybe someone can get some insight from this later. +1 for trying :)
Jason
A: 

You should add the table to the document using Document.Add() if you want automatic splitting of the rows across pages. Then SplitLate and SplitRows will work as expected.

When SplitLate = true (default) the table will be split before the next row that does fit on the page. When SplitLate = false the row that does not fully fit on the page will be split. When SplitRows = true (default) the row that does not fit on a page will be be split. When SplitRows = false the row will be omitted.

So SplitLate && SplitRows: A row that does not fit on the page will be started on the next page and eventually split if it does not fit on that page either.

SplitLate && !SplitRows: A row that does not fit on the page will be started on the next page and omitted if it does not fit on that page either.

!SplitLate && SplitRows: A row that does not fit on the page will be split and continued on the next page and split again if it to last for the next page too.

!SplitLate && !SplitRows: I'm a little unsure about this one. But from the sources it looks like it's the same as SplitLate && !SplitRows: A row that does not fit on the page will be started on the next page and omitted if it does not fit on that page either.

But as for your question: Document.Add() will only be usable if the table is not needed to be absolutely positioned. But it's seems like there is a way to do it though by adding the table to a ColumnText (it's actually a ColumnText object that does all the table splitting) and then absolutyly position that ColumnText. I haven't looked into it yet, but I will as soon as I get a little more time :)

/Asger

asgerhallas
Yes. That can be done. See the AddPTable() method of PdfDocument class in the sources. Hope that helps.
asgerhallas
thanks for this answer but i need to absolutely position my tables. and as i stated in my last comment for @jay riggs' answer, if i don't cut the number of products off at a specific number, i run the risk of having my calculations table split onto two pages. so... yeah, thanks anyways :)
Jason
Your right. I didn't understand your last comment until now :) ... But as for the absolute position, that can be done, just check out how the PdfPTable is added to the document using a ColumnText - that will give you all the automatic table splitting AND the absolute positioning. But if you don't need, then ... keep it simple :)
asgerhallas