reingart / pyfpdf

Simple PDF generation for Python (FPDF PHP port)
https://code.google.com/p/pyfpdf/
GNU Lesser General Public License v3.0
859 stars 527 forks source link

Multi_cell wrapping not working #201

Open mangoez opened 2 years ago

mangoez commented 2 years ago

I tried stack overflow but to no avail, this is probably not a bug but I couldn't find any other way to fix the issue. All I want to automatic raw height and text wrapping! Please let me know what I can do, cheers.

Here is a reproducible example and what it outputs:

from fpdf import FPDF
import pandas as pd

# Detail box
detail_dict = {
    "Pipeline ID": "12345",
    "Date": "31/12/1999",
    "Description": "Meep morp, shoot zappy bois into noggin for science",
    "Dataset": "MNE default finger tapping dataset"
}

detail_col = ["Detail", "Description"]
detail_df = pd.DataFrame(list(zip(list(detail_dict.keys()), list(detail_dict.values()))), columns=detail_col)
detail_df.head()

# A cell is a rectangular area, possibly framed, which contains some text
# Set the width and height of cell
table_cell_width = pdf.epw / detail_df.shape[1]
table_cell_height = pdf.font_size * 2.5

pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 8)

# Loop over to print column names
cols = detail_df.columns
for col in cols:
    pdf.cell(table_cell_width, table_cell_height, col, border=1)

# Line break
pdf.ln(table_cell_height)
# Select a font as Arial, regular, 10
pdf.set_font('Arial', '', 10)

table_cell_heights = [] #list with proper table_cell_height for each row
use_default_height = 0 #flag

#create table_cell_heights of table_cell_heights which size is equal to num rows of data
for row in detail_df.itertuples():
    for col in cols:
        value = str(getattr(row, col))
        word_list = value.split(" ")
        number_of_words = len(word_list) #how many words
        # print(value, number_of_words)
        if number_of_words>2: #names and cities formed by 2 words like Los Angeles are ok)
            use_default_height = 1
            new_table_cell_height = pdf.font_size * (number_of_words) #new height change according to data 
    if not use_default_height:
        table_cell_heights.append(table_cell_height)
    else:
        table_cell_heights.append(new_table_cell_height)
        use_default_height = 0

# Loop over to print each data in the table
# print(table_cell_heights)

row_count = 0
for row in detail_df.itertuples():
    for col in cols:
        value = str(getattr(row, col))
        pdf.multi_cell(table_cell_width, table_cell_heights[row_count], value, border=1, ln=3)
    row_count += 1
    pdf.ln(table_cell_height)

pdf.output('example.pdf')
2022-07-15 13_39_25-example pdf
Lucas-C commented 2 years ago

pyfpdf is not maintained anymore, have you tried using fpdf2? https://pyfpdf.github.io/fpdf2/