I am trying to change font styling of a document as per the user’s input preferences. Eg, if a user inputs to use font Bell MT for style Normal, Helvetica for Heading 1, Bahnschrift for Heading 2 etc and their specific sizes, colour and alignment. I tried the following code but it only changed styles for Normal and not for Heading 1 and 2.
from docx.oxml.ns import qn
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
def set_style(style, font_name, font_size, font_color, alignment):
font = style.font
font.name = font_name
font.size = Pt(font_size)
font.color.rgb = RGBColor(*font_color)
style.paragraph_format.alignment = alignment
set_style(doc.styles['Normal'], 'Bell MT', 12, (0,0,0), WD_ALIGN_PARAGRAPH.JUSTIFY)
set_style(doc.styles['Heading 1'], 'Helvetica', 26, (255,0,0), WD_ALIGN_PARAGRAPH.LEFT)
set_style(doc.styles['Heading 2'], 'Bahnschrift', 20, (0,0,255), WD_ALIGN_PARAGRAPH.LEFT)
So then I researched and found this article. I modified my code as following
from docx.oxml.ns import qn
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
def set_heading_style(heading, font_name, font_size, font_color, alignment):
rFonts = heading.element.rPr.rFonts
rFonts.set(qn("w:asciiTheme"), font_name)
font = heading.font
font.size = Pt(font_size)
font.color.rgb = RGBColor(*font_color)
heading.paragraph_format.alignment = alignment
def set_style(style, font_name, font_size, font_color, alignment):
font = style.font
font.name = font_name
font.size = Pt(font_size)
font.color.rgb = RGBColor(*font_color)
style.paragraph_format.alignment = alignment
set_style(doc.styles['Normal'], 'Bell MT', 12, (0,0,0), WD_ALIGN_PARAGRAPH.JUSTIFY)
set_heading_style(doc.styles['Heading 1'], 'Helvetica', 26, (255,0,0), WD_ALIGN_PARAGRAPH.LEFT)
set_heading_style(doc.styles['Heading 2'], 'Bahnschrift', 20, (0,0,255), WD_ALIGN_PARAGRAPH.LEFT)
This works still for Normal styling but it also sets the font for Heading 1 and 2 as Bell MT. Also the alignment that has been set is JUSTIFY and not LEFT as expected. I think it might have something to do with the fact that Headings are based on Normal, but then color and size should also be “inherited” from Normal. I might be wrong in the above assumption.
I have been calling changing the styles as follows
for i, paragraph in enumerate(doc.paragraphs):
for run in paragraph.runs:
if run.font.size and run.font.size.pt == 24.0:
text = paragraph.text
paragraph.clear()
paragraph.style = 'Heading 1'
paragraph.add_run(text)
if run.font.size and run.font.size.pt == 20.0:
text = paragraph.text
paragraph.clear()
paragraph.style = 'Heading 2'
paragraph.add_run(text)
I am checking for the highest font size and assigning it the paragraph as Heading 1 and so on and clearing any other styling which might have been causing an issue but it didn’t help. I am doing the above checking since when making a document, people don’t generally use different styles but only increase/decrease the font to signify headings/titles.
I don’t know if there is a better way to do what I am trying to achieve, if yes any help would be highly appreciated. My ultimate goal is to format a given document according to the users’ preferences. Like adding a header, footer, cover page etc. I am still working towards that. If anyone could provide me with any resources which might help me please do and thanks a lot in advance.