Another bug with SingleColumnLayoutWithOverflow
siancu opened this issue · 2 comments
I am trying to add a long table with an image in a cell in each row and I'm getting the following error:
Traceback (most recent call last):
File "/Users/si/Developer/github.com/siancu/borb-table-example/main.py", line 57, in <module>
main()
File "/Users/si/Developer/github.com/siancu/borb-table-example/main.py", line 50, in main
layout.add(table)
File "/Users/si/Developer/github.com/siancu/borb-table-example/.venv/lib/python3.11/site-packages/borb/pdf/canvas/layout/page_layout/single_column_layout_with_overflow.py", line 207, in add
super(SingleColumnLayoutWithOverflow, self).add(t)
File "/Users/si/Developer/github.com/siancu/borb-table-example/.venv/lib/python3.11/site-packages/borb/pdf/canvas/layout/page_layout/multi_column_layout.py", line 205, in add
assert False, f"{layout_element.__class__.__name__} is too tall to fit inside column / page. Needed {round(layout_box.get_height())} pts, only {round(available_box.get_height())} pts available."
AssertionError: FixedColumnWidthTable is too tall to fit inside column / page. Needed 521 pts, only 476 pts available.
If I remove the image and put a Paragraph with a text in it, then it works. I made a table with approx. 200 rows without problems.
However, once I add the image, it breaks even with 3 rows (it works with 2). It breaks when it should go to the next page.
Here is the script that reproduces the issue. The image is a png file with the size 250x156.
from decimal import Decimal
from pathlib import Path
from borb.pdf import Document
from borb.pdf import FixedColumnWidthTable
from borb.pdf import PDF
from borb.pdf import Page
from borb.pdf import Paragraph
from borb.pdf import SingleColumnLayoutWithOverflow
from borb.pdf import Image
from borb.pdf.page.page_size import PageSize
doc = Document()
page = Page(PageSize.A4_LANDSCAPE.value[0], PageSize.A4_LANDSCAPE.value[1]) # A4 Landscape
doc.add_page(page)
# with 2 it works, with 3 it doesn't
# number_of_samples = 2
number_of_samples = 3
layout = SingleColumnLayoutWithOverflow(page)
table = FixedColumnWidthTable(
number_of_columns=7,
number_of_rows=number_of_samples + 1,
column_widths=[Decimal(2), Decimal(6), Decimal(1), Decimal(2), Decimal(1), Decimal(2), Decimal(1)],
)
# add the table header
table.add(Paragraph("Sample ID", font="Helvetica-Bold"))
table.add(Paragraph("Image", font="Helvetica-Bold"))
table.add(Paragraph("Valid", font="Helvetica-Bold"))
table.add(Paragraph("Data Mode", font="Helvetica-Bold"))
table.add(Paragraph("Other Mode", font="Helvetica-Bold"))
table.add(Paragraph("Some float", font="Helvetica-Bold"))
table.add(Paragraph("Done", font="Helvetica-Bold"))
for i in range(number_of_samples):
table.add(Paragraph(f"Sample_{i}"))
table.add(Image(Path("./sample.png"), width=Decimal(250), height=Decimal(156)))
table.add(Paragraph("yes"))
table.add(Paragraph("increasing"))
table.add(Paragraph("="))
table.add(Paragraph("4.342E+00"))
table.add(Paragraph("no"))
table.set_padding_on_all_cells(Decimal(2), Decimal(2), Decimal(2), Decimal(2))
layout.add(table)
with open("/Users/si/Desktop/output.pdf", "wb") as out_file_handle:
PDF.dumps(out_file_handle, doc)
Here is the image I used:
This works in the latest release of borb (possibly previous releases as well, considering I don't think I changed SingleColumnLayoutWithOverflow
).
I changed your test to the following code (you had multiple issues with text not fitting inside the columns you'd defined:
def test_singlecolumnlayoutwithoverflow_with_images(self):
pdf: Document = Document()
page: Page = Page()
pdf.add_page(page)
layout: SingleColumnLayoutWithOverflow = SingleColumnLayoutWithOverflow(page)
number_of_samples: int = 5
table = FixedColumnWidthTable(
number_of_columns=7,
number_of_rows=number_of_samples + 1,
column_widths=[Decimal(2), Decimal(6), Decimal(1), Decimal(2), Decimal(1), Decimal(2), Decimal(1)],
)
# add the table header
table.add(Paragraph("S", font="Helvetica-Bold"))
table.add(Paragraph("I", font="Helvetica-Bold"))
table.add(Paragraph("V", font="Helvetica-Bold"))
table.add(Paragraph("D", font="Helvetica-Bold"))
table.add(Paragraph("O", font="Helvetica-Bold"))
table.add(Paragraph("S", font="Helvetica-Bold"))
table.add(Paragraph("D", font="Helvetica-Bold"))
image_url: str = "https://images.unsplash.com/photo-1568322445389-f64ac2515020"
for i in range(number_of_samples):
table.add(Paragraph(f"Sample_{i}"))
table.add(Image(image_url, width=Decimal(180), height=Decimal(156)))
table.add(Paragraph("y"))
table.add(Paragraph("i"))
table.add(Paragraph("="))
table.add(Paragraph("4"))
table.add(Paragraph("n"))
table.set_padding_on_all_cells(Decimal(2), Decimal(2), Decimal(2), Decimal(2))
layout.add(table)
with open(self.get_second_output_file(), "wb") as out_file_handle:
PDF.dumps(out_file_handle, pdf)
when number_of_samples
is set to 3
, everything fits on a single Page
.
So I set it to 5
, and it splits, as expected.
Just a heads-up, I will change the test to make the content a bit more generic.
So you won't find an exact match (this test code) in the repo. But the name should be the same.