Search code examples
pythonpdf-generationborb

borb pdf library - issue with right alignment with € symbol and border bottom in tables


I'm using borb pdf library in python to create a pdf file with Tables. I have found 2 issues that I can't fix so far, probably because I started using this library recently:

  • Issue with right alignment in a TableCell when text string uses € symbol.
  • Issue with border_bottom that does not reach the end of the text string when having accent letters.

Below you can find the python code I'm testing.

table_001 - row 1, does not use accent letters and the border_bottom looks ok. table_001 - row 2, string does not have € symbol at the end and it's correctly right aligned.

table_002 - row 1, uses accent letters and the border_bottom looks truncated. table_001 - row 2, string has € symbol at the end and it's not correctly right aligned.

from borb.pdf import Document
from borb.pdf import Page
from borb.pdf import SingleColumnLayout
from borb.pdf import PageLayout
from decimal import Decimal
from borb.pdf import FixedColumnWidthTable
from borb.pdf import Paragraph
from borb.pdf import Alignment
from borb.pdf import HexColor, X11Color
from borb.pdf import TableCell
from borb.pdf import PDF


def main():
    # Create document
    pdf = Document()

    # Add page
    page = Page()
    pdf.add_page(page)

    # create PageLayout
    page_layout: PageLayout = SingleColumnLayout(page)
    page_layout.vertical_margin = page.get_page_info().get_height() * Decimal(0.02)

    table_001 = FixedColumnWidthTable(number_of_rows=2, number_of_columns=2)
    table_001.add(
        Paragraph(
            'Direccion Facturacion:', font_size=Decimal(9), border_bottom=True
        )
    )
    table_001.add(
        Paragraph(
            "Direccion de Envio:", font_size=Decimal(9), border_bottom=True
        )
    )
    table_001.add(TableCell(Paragraph("190,00", font_size=Decimal(9)), background_color=HexColor("BBBBBB")))
    table_001.add(TableCell(Paragraph("190,00", font_size=Decimal(9), horizontal_alignment=Alignment.RIGHT),
                            background_color=HexColor("BBBBBB")))
    # table_001.set_padding_on_all_cells(Decimal(2), Decimal(2), Decimal(2), Decimal(2))
    # table_001.no_borders()

    table_002 = FixedColumnWidthTable(number_of_rows=2, number_of_columns=2)
    table_002.add(
        Paragraph(
            'Dirección Facturación:', font_size=Decimal(9), border_bottom=True
        )
    )
    table_002.add(
        Paragraph(
            "Dirección de Envío:", font_size=Decimal(9), border_bottom=True
        )
    )
    table_002.add(TableCell(Paragraph("190,00 €", font_size=Decimal(9)), background_color=HexColor("BBBBBB")))
    table_002.add(TableCell(Paragraph("190,00 €", font_size=Decimal(9), horizontal_alignment=Alignment.RIGHT),
                            background_color=HexColor("BBBBBB")))

    page_layout.add(table_001)
    page_layout.add(Paragraph(" "))
    page_layout.add(table_002)

    # store
    with open("test.pdf", "wb") as out_file_handle:
        PDF.dumps(out_file_handle, pdf)


if __name__ == "__main__":
    main()

If I replace the € symbol with the $ symbol, right alignment works fine.

This is the output pdf: https://github.com/davdiaz/hello-wold/blob/master/test.pdf


Solution

  • Disclaimer: I am the author of borb

    The main problem in your answer is definitely the font metrics. Font metrics is a fancy way of saying "the font needs to know how wide/tall every character is"

    When the font metrics are screwed up, you might get effects such as:

    • text is not underlined (because some characters do not have a width, and the text width is not calculated correctly)
    • text alignment goes wrong (because alignment depends on being able to calculate the width of a piece of text)

    I think the most basic case for your problem would be:

    • create an empty PDF
    • add an empty page
    • add a single piece of text containing only an accented character (default font Helvetica)
    • add a border round the text

    After checking the code, and the use-case I've outlined above, I discovered there was a bug in borb.

    It is fixed, and I am now running tests.