Question: I am trying to create a pdf document that includes a table. For each row of the table, a transaction will be recorded, and I would like the 4th column to include a paperclip image (or emoji) with a hyperlink to a document stored online. I would also like the 6th column to include tag names with a specific background color associated with each tag name, ideally with the background as a rounded rectangle. So far I am not able to put different backgrounds for a single cell. I have thought about creating one row per tag, and merge the cells for all the other columns, but I am not sure it would be the best option as sometimes several tags could fit in one line. So far I have: from datetime import datetime from decimal import Decimal from pathlib import Path from borb.pdf.canvas.font.simple_font.true_type_font import TrueTypeFont from borb.pdf.canvas.color.color import HexColor from borb.pdf.canvas.layout.layout_element import Alignment from borb.pdf.canvas.layout.table.fixed_column_width_table import FixedColumnWidthTable as Table from borb.pdf.canvas.layout.table.table import TableCell from borb.pdf.canvas.layout.text.paragraph import Paragraph from borb.pdf.canvas.layout.annotation.remote_go_to_annotation import RemoteGoToAnnotation from borb.pdf.canvas.geometry.rectangle import Rectangle from borb.pdf.canvas.layout.emoji.emoji import Emojis rubik = TrueTypeFont.true_type_font_from_file(Path(__file__).parent / "fonts/Rubik-Regular.ttf") rubik_medium = TrueTypeFont.true_type_font_from_file(Path(__file__).parent / "fonts/Rubik-Medium.ttf") background_color = HexColor("#FF5733") def generate_table(transactions): table = Table(number_of_rows=1 + len(transactions), number_of_columns=6, horizontal_alignment=Alignment.JUSTIFIED, column_widths=[Decimal(60), Decimal(60), Decimal(220), Decimal(30), Decimal(50), Decimal(50),Decimal(80)]) table.add(TableCell(Paragraph("Date", font=rubik_medium, font_size=Decimal(11), horizontal_alignment=Alignment.CENTERED))) table.add(TableCell(Paragraph("Account", font=rubik_medium, font_size=Decimal(11), horizontal_alignment=Alignment.CENTERED))) table.add(TableCell(Paragraph("Description", font=rubik_medium, font_size=Decimal(11), horizontal_alignment=Alignment.CENTERED))) table.add(TableCell(Paragraph("Attachment", font=rubik_medium, font_size=Decimal(11), horizontal_alignment=Alignment.CENTERED))) table.add(TableCell(Paragraph("Value", font=rubik_medium, font_size=Decimal(11), horizontal_alignment=Alignment.CENTERED))) table.add(TableCell(Paragraph("Tags", font=rubik_medium, font_size=Decimal(11), horizontal_alignment=Alignment.CENTERED))) for transaction in transactions: # Column 1 table.add(TableCell(Paragraph(datetime.strftime(transaction[0], '%d/%m/%y'), font=rubik, font_size=Decimal(8)))) # Column 2 table.add(TableCell(Paragraph(transaction[1], font=rubik, font_size=Decimal(8), horizontal_alignment=Alignment.CENTERED))) # Column 3 table.add(TableCell(Paragraph(transaction[2], font=rubik, font_size=Decimal(8), horizontal_alignment=Alignment.CENTERED))) # Basically I would need to somehow merge the following lines as my column 4 table.add(TableCell(RemoteGoToAnnotation(Rectangle(Decimal(32), Decimal(32), Decimal(32), Decimal(32)), uri=transaction[3]))) table.add(TableCell(Emojis.PAPERCLIP.value)) # Column 5 table.add(TableCell(Paragraph(f"{transaction[4]:.2f}", font=rubik, font_size=Decimal(8), horizontal_alignment=Alignment.CENTERED))) # Column 6 table.add(TableCell(Paragraph("\n".join(transaction[5]), font=rubik, font_size=Decimal(8), border_radius_top_left=Decimal(10), border_radius_top_right=Decimal(10), border_radius_bottom_left=Decimal(10), border_radius_bottom_right=Decimal(10), background_color=background_color, horizontal_alignment=Alignment.CENTERED))) 

Answer: disclaimer: I am the author of borb. import random import typing from _decimal import Decimal from borb.pdf import PDF, Document, Page, FlexibleColumnWidthTable, Table, Paragraph, Lipsum, HeterogeneousParagraph, \ ChunkOfText, HexColor, Color, PageLayout, SingleColumnLayout from borb.pdf.canvas.layout.annotation.remote_go_to_annotation import RemoteGoToAnnotation from borb.pdf.canvas.layout.emoji.emoji import Emojis from borb.pdf.canvas.layout.layout_element import LayoutElement def main(): # empty Document doc: Document = Document() # add empty Page page: Page = Page() doc.add_page(page) # layout layout: PageLayout = SingleColumnLayout(page) # build Table t: Table = FlexibleColumnWidthTable(number_of_columns=6, number_of_rows=5) # header t.add(Paragraph("Date", font="Helvetica-Bold")) t.add(Paragraph("Account", font="Helvetica-Bold")) t.add(Paragraph("Description", font="Helvetica-Bold")) t.add(Paragraph("Attachment", font="Helvetica-Bold")) t.add(Paragraph("Value", font="Helvetica-Bold")) t.add(Paragraph("Tags", font="Helvetica-Bold")) # data elements_to_add_annotations_for: typing.List[LayoutElement] = [] for _ in range(0, 4): t.add(Paragraph("04/01/1989")) t.add(Paragraph("Joris Schellekens")) # random description t.add(Paragraph(Lipsum.generate_lipsum_text(2), font_size=Decimal(5))) # emoji # we need to be able to access the position later, so we store the LayoutElement e: LayoutElement = Emojis.SMILE.value elements_to_add_annotations_for += [e] t.add(e) # random value t.add(Paragraph(random.choice(["Good", "Very good", "Above expectations"]))) # random tags tags: typing.List[str] = [] tags += [random.choice(["lorem", "ipsum", "dolor"])] tags += [random.choice(["sit", "amet", "consectetur"])] tags += [random.choice(["adipiscing", "elit", "sed"])] # define the colors for the tags possible_colors_for_tags: typing.List[Color] = [HexColor("ff595e"), HexColor("ffca3a"), HexColor("8ac926"), HexColor("1982c4"), HexColor("6a4c93")] colors: typing.List[Color] = [random.choice(possible_colors_for_tags) for _ in tags] t.add(HeterogeneousParagraph(chunks_of_text=[ChunkOfText(x, background_color=colors[i], border_color=colors[i], border_radius_bottom_left=Decimal(5), border_radius_bottom_right=Decimal(5), border_radius_top_left=Decimal(5), border_radius_top_right=Decimal(5), border_bottom=True, border_top=True, border_left=True, border_right=True) for i,x in enumerate(tags)])) # add Table to Page t.set_padding_on_all_cells(Decimal(5), Decimal(5), Decimal(5), Decimal(5)) layout.add(t) # add Annotation(s) for e in elements_to_add_annotations_for: page.add_annotation(RemoteGoToAnnotation(e.get_previous_paint_box(), "https://www.borbpdf.com/")) # write with open("output.pdf", "wb") as fh: PDF.dumps(fh, doc) if __name__ == "__main__": main()  Some of the finer details of this snippet:  I used the Lipsum class to generate a random description By keeping track of the LayoutElement it becomes easy to add an Annotation later. Annotation objects require a bounding box, and LayoutElement keeps track of where it was painted. HeterogeneousParagraph allows you to merge other (text-carrying) LayoutElement objects inside it. That is how I implemented the tags. I also set their borders, giving each a border_radius to really enhance the "tag feel".  The final PDF looks something like this: