Search code examples
reportlab

Additional question mark printed with line breaks using reportlab XPreformatted


I'm using XPreformatted to print some preformated text and I have an issue with the line breaks.

The line breaks are correctly translated but additionally I get a "question mark" at the end of each line.

This is my output:

first line?
second line?
some more text

I'm using django with mysql and the database field is a simple varchar field.

I checked it in the database and everything what is between the "e" and the "s" in "first linE Second line" is a new line character.

With new line character I mean what is entered in the database when I press "enter" ;-)

Thus for me it seems strange that on the one hand the new line is correctly interpreted as a new line and additionally there is a wrong question mark.


Solution

  • ok I know now how to circumvent this behavior. I just remove the character which is before the \n . Its the byte character 13. Thus I created a gready repair algorithm to remove this character and my pdf generating world is fine again ;-)

    def repair_string_for_xpreformatted_use(value):
        #remove element before \n
        #it is an empty element interpreted from XPreformatted as a question mark
        #i guess this element is coming from the mysql db. test it with postgres db!
        #this is definitely a greedy repair algorithm
    
        lb_index = value.find('\n')
        start_index = 0
        end_index = len(value)
        value_rep = ""
        while lb_index != -1:
            lb_index = value.find('\n', 1)
            byte_list = toBytes(value[lb_index-1])
            if byte_list[0] == 13:
                #13 is the strange byte character which should not be there. remove it.. bye bye number 13
                value_rep += value[start_index:lb_index-1]
            else:
                #do not remove the character. we do not want to strip some user information ;-)
                value_rep += value[start_index:lb_index]
    
            value = value[lb_index:end_index]
            if lb_index == (end_index -1) or lb_index == end_index:
                lb_index = -1
            end_index = len(value)
        return value_rep
    

    How to use it:

    from reportlab.platypus import XPreformatted
    footerstyle = ParagraphStyle(name='footerstyle', leading=6, spaceBefore=0, spaceAfter=0, textColor=gray2, fontName='Calibri', fontSize=5, alignment=TA_RIGHT)
    footer_text_rep = repair_string_for_xpreformatted_use(footer_text)
    footer_text_pre = XPreformatted(smart_str(footer_text_rep), footerstyle)