rkusa / pdfjs

A Portable Document Format (PDF) generation library targeting both the server- and client-side.
MIT License
786 stars 142 forks source link

Page Breaks across table rows prevent headers from appearing #292

Open KindaOK opened 2 years ago

KindaOK commented 2 years ago

When a row has a page break within it, the current behavior is that table headers are not inserted. If there are other rows, however, then having no table headers seems incorrect. Sample output here: header-split.result.pdf (code as a unit test below). Is this the expected behavior? It doesn't seem right in the sample output. Existing unit tests also don't have any great examples of this because the only ones with rows across page breaks don't have any following rows.

module.exports = function(doc, { lorem })  {
  const table = doc.table({
    widths: [200, 200],
    borderWidth: 1,
  })

  const header = table.header()
  header.cell('Header Left', { textAlign: 'center', padding: 30, paddingTop: 100 })
  header.cell('Header Right', { textAlign: 'center', padding: 30, paddingTop: 100})

  const row1 = table.row()

  row1.cell(lorem.long, { fontSize: 11, padding: 10, backgroundColor: 0xdddddd })
  row1.cell('Cell 2', { fontSize: 11, padding: 10, backgroundColor: 0xeeeeee })

  const row2 = table.row()

  row2.cell(lorem.long, { fontSize: 16, padding: 10, backgroundColor: 0xdddddd })
  row2.cell('Cell 2', { fontSize: 11, padding: 10, backgroundColor: 0xeeeeee })

  const row3 = table.row()

  row3.cell('Cell 1', { fontSize: 16, padding: 10, backgroundColor: 0xdddddd })
  row3.cell(lorem.short, { fontSize: 11, padding: 10, backgroundColor: 0xeeeeee })

  doc.text('Foo')
}
rkusa commented 1 year ago

IIRC, this was done on purpose as it was a requirement of the project I wrote this lib for in the first place. It isn't used there anymore, so I am open for changing this. However, I am honestly not sure what the best solution (best in terms of what most would expect) of the following would be:

  1. Don't add the header in this case (current behaviour)
  2. Add the table header at the top of the page (so basically in-between the row that got split)
  3. Add the table header below the row that got split (so basically somewhere in the middle of the page)

I'd personally expect either (1) or (2).

If anyone else is reading this, feel free to jump in with an opinion what your expected behaviour would be.

KindaOK commented 1 year ago

I personally prefer 2, but the existing behavior (1) seems to be fine in most scenarios. I would need to do some more testing, but I think that this situation only crops up when you force it to with large rows. Again, I should probably verify this.

Edit: The default behavior is pretty good about splitting eagerly, especially with small rows. You need pretty tall rows to get this kind of behavior. Since the use case for tables is almost always short rows, it's not too big of a problem.