Change styles for complete document

Hi we are trying to change style of document, there are few issues that are seen and need support for resolving the issues
we are using the below function to change the font name and font size

def rebrand_document(self, file_path):
        t0 = time.perf_counter()
        base = os.path.splitext(os.path.basename(file_path))[0].replace(" ", "_")
        out_dir = os.path.join("/test/",base)
        os.makedirs(out_dir, exist_ok=True)
        out_path = os.path.join(out_dir, f"{base}.docx")


        try:
            doc = aw.Document(file_path)

            # Define helper to change font of runs if matches criteria
            def change_font(run):
                try:
                    font_name = (run.font.name or "").strip().lower()
                    if font_name in ["arial", "times new roman"]:
                        size = float(run.font.size)
                        run.font.name = self.target_font_name
                        if isclose(size, 12.0, abs_tol=0.01):
                            run.font.size = 11.0
                except Exception as e:
			print(e)

            # Process all runs in document (deep)
            try:
                runs = doc.get_child_nodes(aw.NodeType.RUN, True)
                run_count = runs.count
                for i in range(run_count):
                    run = runs[i].as_run()
                    change_font(run)
            except Exception as e:
		print(e)

            # Process footnotes
            try:
                footnotes = doc.get_child_nodes(aw.NodeType.FOOTNOTE, True)
                footnote_count = footnotes.count
                for i in range(footnote_count):
                    footnote = footnotes[i].as_footnote()
                    para_count = footnote.paragraphs.count
                    for j in range(para_count):
                        para = footnote.paragraphs[j]
                        run_count = para.runs.count
                        for k in range(run_count):
                            change_font(para.runs[k])
            except Exception as e:
		print(e)

            # Process headers and footers
            try:
                section_count = doc.sections.count
                for s in range(section_count):
                    section = doc.sections[s]
                    hf_count = section.headers_footers.count if section.headers_footers is not None else 0
                    for h in range(hf_count):
                        hf = section.headers_footers[h]
                        if hf is not None:
                            para_count = hf.paragraphs.count
                            for p in range(para_count):
                                para = hf.paragraphs[p]
                                run_count = para.runs.count
                                for r in range(run_count):
                                    change_font(para.runs[r])
            except Exception as e:
		print(e)

            # Process shapes (which may contain text)
            try:
                shapes = doc.get_child_nodes(aw.NodeType.SHAPE, True)
                shape_count = shapes.count
                for i in range(shape_count):
                    shape = shapes[i].as_shape()

                    # Use get_text_frame() method to check for text
                    try:
                        text_frame = shape.get_text_frame()
                    except AttributeError:
                        text_frame = None

                    if text_frame is not None:
                        para_count = text_frame.paragraphs.count
                        for j in range(para_count):
                            para = text_frame.paragraphs[j]
                            run_count = para.runs.count
                            for k in range(run_count):
                                change_font(para.runs[k])
            except Exception as e:
		print(e)

            # Update document layout before saving
            try:
                doc.update_page_layout()
            except Exception as e:
		print(e)

            try:
                doc.save(out_path)
            except Exception as e:
                
                return out_path, e

            t1 = time.perf_counter()
            return out_path, "OK"

        except Exception as e:
		print(e)

issues are,

  1. when we open the saved file and enter new word/sentence the text is seen in either airal /times new roman

  2. the bullet points are not changing the font size/font name

  3. when the font size and name are changed if any flow charts are word wrapped their location are changing

can you please help in resolution using python?

@Prakruth

To address the issues you’re facing with changing the styles in your document, let’s break down each problem and provide clear solutions.

  1. New Text Appearing in Default Fonts: This issue typically arises when the default styles in the document are not updated. To ensure that new text uses the desired font, set the default font for the document. You can do this by accessing the default_font property of the StyleCollection and setting it to your target font. Here’s how you can do it:

    doc.styles.default_font.name = self.target_font_name
    doc.styles.default_font.size = 11.0  # Set the default size as needed
    
  2. Bullet Points Not Changing Font Size/Name: Bullet points are often controlled by the paragraph styles. Ensure that the styles applied to the bullet points are also updated. You can iterate through the styles and update the bullet point styles specifically. Here’s an example:

    for style in doc.styles:
        if style.type == aw.StyleType.PARAGRAPH and style.list_format.list:
            style.font.name = self.target_font_name
            style.font.size = 11.0  # Adjust as needed
    
  3. Flow Charts Changing Location: This issue may occur due to the way text wrapping is handled when changing font sizes. To prevent flow charts from moving, ensure that you are not altering the layout properties of the shapes. Check the TextFrame properties of the shapes and ensure they are set correctly after changing the font.

    If you are using shapes with text, set the text wrapping style explicitly:

    for shape in doc.get_child_nodes(aw.NodeType.SHAPE, True):
        text_frame = shape.get_text_frame()
        if text_frame:
            text_frame.text_wrap = True  # Ensure text wrapping is enabled
    

Next Steps:

  • Implement the above code snippets in your rebrand_document function.
  • Test the document after making these changes to confirm that the issues are resolved.
  • If problems persist, review the document’s styles to ensure that all relevant styles are being updated.

Please proceed with these steps, and let me know if you need further assistance or clarification!

@Prakruth Could you please attach your input document, your current and expected output documents? We will check the issue and provide you more information.
Is you goal simply change font name and size in the document?

schedule.docx (76.7 KB)

Please find the attached document, we are able to change style(font name from “Times New Roman” to “Aptos”) but the font name is not reflecting when the document is saved and re-opened.
Same is the case with numbering

Thank you for additional information. Please try using the following code to change font in the document:

def change_font(font) :
    font.name = "Aptos"
    font.size = 10
doc = aw.Document("C:\\Temp\\in.docx")

for n in doc.get_child_nodes(aw.NodeType.ANY, True):
    match n.node_type:
        case aw.NodeType.RUN:
            change_font(n.as_run().font)
        case aw.NodeType.PARAGRAPH:
            change_font(n.as_paragraph().paragraph_break_font)
        case aw.NodeType.FIELD_START:
            change_font(n.as_field_start().font)
        case aw.NodeType.FIELD_END:
            change_font(n.as_field_end().font)
        case aw.NodeType.FIELD_SEPARATOR:
            change_font(n.as_field_separator().font)
        case aw.NodeType.FOOTNOTE:
            change_font(n.as_footnote().font)
        case aw.NodeType.FORM_FIELD:
            change_font(n.as_form_field().font)
        case aw.NodeType.SPECIAL_CHAR:
            change_font(n.as_special_char().font)
    
doc.save("C:\\Temp\\out.docx")

thanks for quick response, but this code worked for me

   doc = aw.Document(input_path)
  #1) Retarget base styles so newly-typed text also uses the new font
    for style in doc.styles:
        if style.type in (aw.StyleType.PARAGRAPH, aw.StyleType.CHARACTER, aw.StyleType.TABLE):
            f = style.font
            f.name = font_name
            f.name_bi = font_name
            f.name_far_east = font_name


    # changes to styles
    for name in ("Normal", "Default Paragraph Font", "Heading 1", "Heading 2", "Heading 3"):
        st = doc.styles.get_by_name(name)
        if st is not None:
            f = st.font
            f.name = font_name
            f.name_bi = font_name
            f.name_far_east = font_name


    # 2) Ensure list numbers/bullets (labels) use the new font & size
    for i in range(doc.lists.count):
        lst = doc.lists[i]
        lvls = lst.list_levels
        for j in range(lvls.count):
            lf = lvls[j].font
            lf.name = font_name
            lf.name_bi = font_name
            lf.name_far_east = font_name


    # 3) Force-update every existing run (deep scan: body, headers/footers, shapes, notes, comments, etc.)
    runs = doc.get_child_nodes(aw.NodeType.RUN, True)  # True = deep
    for k in range(runs.count):
        r = runs[k].as_run()
        f = r.font
        f.name = font_name
        f.name_bi = font_name
        f.name_far_east = font_name


    # 4) Refresh dynamic content (e.g., TOC) so its display reflects style changes
    doc.update_fields()

@Prakruth Your code des almost the same as I have proposed. The only difference my code changes explicit formatting applied to the nodes in the document. You can replace the 3rd stage of your code with code I have proposed to make sure font is applied to whole document’s content.

follow up question on change of styles
when we are changing the font in text box in attached document say to “Aptose” like early, certain data in text box is getting hidden due to text box property, can we fix the dimensions according to text in text box without overlay?
flowchart.docx (47.6 KB)

@Prakruth You can try setting TextBox.fit_shape_to_text property to resolve this problem. but this might affect the layout.
Unfortunately, there is no easy way to fix this whiteout affecting the original shapes layout.