Search code examples
pythonpython-docx

How do create a new line break in python-doxc that has a specified character size?


I currently have a paragraph as a header that is Pt48 in size and I want to create a new line break using add_break() which works perfectly fine but it inherits the top paragraph character size. Is there a way to specify the new line break character size. I've look at the documentation and I cannot find anything that can do this. Line Break Reference | Working with Text Refrence

Some code for reference

document = Document()

initiate_all_styles(document)

invoice_header = document.add_paragraph(style='invoice')
invoice_header_run = invoice_header.add_run('INVOICE')
invoice_header_run.bold = True
invoice_header_run.add_break()

document.save('invoice.docx')

Styles code

def initiate_all_styles(document):
  initiate_invoice_style(document)
  #other methods for styles located here

def initiate_invoice_style(document):
  font_styles = document.styles
  font_charstyle = font_styles.add_style('invoice', WD_STYLE_TYPE.PARAGRAPH)
  font_charstyle.font.color.rgb = RGBColor.from_string(MAIN_COLOR)
  font_object = font_charstyle.font
  font_object.size = Pt(48)
  font_object.name = 'Arial'

Edit:
My current solution for this is to create an invisible paragraph with a character that matched the background colour and set the size to my desired spacing Pt(10).

This is definitely not a great solution and more of a hack but it works. This also takes a extra couple lines of code rather then potentially adding 1 and maintaining it also pain in the butt.

invisible_character = document.add_paragraph('-', style='invisible')
invisible_character.paragraph_format.line_spacing = ONE_DOT_ZERO_LINE_SPACING
invisible_character.paragraph_format.space_after = ZERO_SPACE_AFTER

Solution

  • Seems you don't really understood the concept of paragraphs and text-runs in Word.

    Paragraphs always are followed by a line break. No need to set one. The space between paragraphs is determined by space after set for this paragraph and space before set for next paragraph.

    Paragraphs contain text-runs. Each tex-run may have different font-formatting. But there cannot be different font-formatting in one single text-run, even not after a line break.

    A line break in a text-run get used when the text-line shall break but without creating a new paragraph. This is a very rare use case because Word automatically breaks lines when text reaches the right page margin.

    Following code produces what I think you want to achieve:

    from docx import Document
    from docx.shared import RGBColor, Pt
    from docx.enum.style import WD_STYLE_TYPE
    
    MAIN_COLOR = '0000FF'
    
    def initiate_all_styles(document):
      invoice_paragraph_style = document.styles.add_style('invoice', WD_STYLE_TYPE.PARAGRAPH)
      invoice_paragraph_style.font.color.rgb = RGBColor.from_string(MAIN_COLOR)
      invoice_paragraph_style.font.size = Pt(48)
      invoice_paragraph_style.font.name = 'Arial'
      invoice_paragraph_style.paragraph_format.line_spacing = 1.0
      invoice_paragraph_style.paragraph_format.space_before = Pt(0)
      invoice_paragraph_style.paragraph_format.space_after = Pt(0)
      
      default_paragraph_style = document.styles.add_style('default', WD_STYLE_TYPE.PARAGRAPH)
      #default_paragraph_style.font.color.rgb = RGBColor.from_string(MAIN_COLOR) # default color is black
      default_paragraph_style.font.size = Pt(10)
      default_paragraph_style.font.name = 'Arial'
      default_paragraph_style.paragraph_format.line_spacing = 1.0
      default_paragraph_style.paragraph_format.space_before = Pt(0) 
      default_paragraph_style.paragraph_format.space_after = Pt(0) 
      
        
    document = Document()
    
    initiate_all_styles(document)
    
    invoice_header = document.add_paragraph(style='invoice')
    invoice_header_run = invoice_header.add_run('INVOICE')
    invoice_header_run.bold = True
    #invoice_header_run.add_break() # why?
    invoice_first_paragraph = document.add_paragraph(style='default')
    invoice_first_paragraph_run = invoice_first_paragraph.add_run('Lorem ipsum...')
    invoice_first_paragraph_run.add_break()
    invoice_first_paragraph_run = invoice_first_paragraph.add_run('semit dolor...')
    
    document.save('invoice.docx')