I'm using the method multicell() of the class FPDF
(library PyFPDF) and, to manage it in my real application, I have to use the method get_string_width().
multi_cell.pdf
.get_num_of_lines_in_multicell(pdf, message)
which tries to calculate the number of lines the text is divided into the multicell. The function uses the method get_string_width() of the class FPDF.from fpdf import FPDF
import webbrowser
CELL_WIDTH = 20
# function that calculates the number of lines inside multicel
def get_num_of_lines_in_multicell(pdf, message):
n = 1
msg_width = pdf.get_string_width(message)
while msg_width > n * CELL_WIDTH:
n += 1
return n
def main():
pdf=FPDF()
pdf.add_page()
pdf.set_font('Arial','',8)
cell_message1 = "Hello World! I'm trying to use multi_cell() method"
pdf.multi_cell(CELL_WIDTH, 4, cell_message1, 1, 0)
# call the function get_num_of_lines_in_multicell() and print the number of lines inside the multicell
print(f"num lines in the multi_cell = {get_num_of_lines_in_multicell(pdf, cell_message1)}")
# creation of the PDF
pdf.output('multi_cell.pdf','F')
# open the PDF
webbrowser.open_new('multi_cell.pdf')
main()
The output of the file on the standard output is the followed:
num lines in the multi_cell = 4
But the multicell inside the PDF file created contains the message on 5 LINES and not 4 LINES. Below I show the PDF content:
Where is the error in the function get_num_of_lines_in_multicell(pdf, message)
which return 4 lines, while in the file created the lines are 5?
The function get_num_of_lines_in_multicell()
doesn't use correctly the method get_string_width()
. This method is called only one time on the whole string. This is correct if the string would be inserted in a normal cell, but not if it is split between multiple rows like the multi_cell()
method does.
To solve the problem it is necessary to consider all the words present in the message and apply get_string_width()
to a string that is built by adding one word at a time.
The correct function get_num_of_lines_in_multicell()
is shown below along with the entire program:
from fpdf import FPDF
import webbrowser
CELL_WIDTH = 20
# correct function which calculates the number of lines inside multicell
def get_num_of_lines_in_multicell(pdf, message):
# divide the string in words
words = message.split(" ")
line = ""
n = 1
for word in words:
line += word + " "
line_width = pdf.get_string_width(line)
# In the next if it is necessary subtract 1 to the WIDTH
if line_width > CELL_WIDTH - 1:
# the multi_cell() insert a line break
n += 1
# reset of the string
line = word + " "
return n
def main():
pdf=FPDF()
pdf.add_page()
pdf.set_font('Arial','',8)
cell_message1 = "Hello World! I'm trying to use multi_cell() method"
pdf.multi_cell(CELL_WIDTH, 4, cell_message1, 1, 0)
print(f"correct num lines in the multi_cell = {get_num_of_lines_in_multicell(pdf, cell_message1)}")
cell_message2 = "Hello World! I'm trying to use multi_cell() method. Now check where is"
pdf.multi_cell(CELL_WIDTH, 4, cell_message2, 1, 0)
print(f"correct num lines in the multi_cell = {get_num_of_lines_in_multicell(pdf, cell_message2)}")
pdf.output('multi_cell.pdf','F')
webbrowser.open_new('multi_cell.pdf')
main()
The output of the execution of the program is:
correct num lines in the multi_cell = 5
correct num lines in the multi_cell = 7
And the file multi_cell.pdf
contains the following cells: