How to calculate the number of rows filled by a string in a multi_cell with the library PyFPDF?

Question:

I’m trying to use the class FPDF of the library PyFPDF.
In particular I’m using the method multicell() od the class FPDF and, to manage it in my real application, I have to use the method get_string_width().

Description of my code

  • The code below creates a PDF file called multi_cell.pdf.
  • Inside the PDF I have inserted only a multicell which contains the message:
    "Hello World! I'm trying to use multi_cell() method".
  • The code implements also the function get_num_of_lines_in_multicell(pdf, message) which tries to calculates the number of lines present inside the multicell. The function uses the method get_string_width() of the class FPDF.

The code with its output

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:

Content of the pdf created

Question

Someone can help me to find where is the error in the function get_num_of_lines_in_multicell(pdf, message) which return 4 lines, while in the file the lines are 5?

Asked By: frankfalse

||

Answers:

The incorrect use of get_string_width()

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.

How to fix the function get_num_of_lines_in_multicell()

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 multicel
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 program

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:

pdf with 2 multi_cell

Answered By: frankfalse
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.