ARTICLE AD BOX
I'm using Python with pywin32 to find and replace text in a Word document (.docx).
The code finds the target string "123", but when I save the document with the replaced strings to a new file (b.docx), the content remains unchanged—the original text appears instead of the replaced text.
My current code iterates through all StoryRanges and also checks Shapes in headers/footers:
The problematic behavior:
- Input file (a.docx) contains: "Dahio1213dnuaidhaoi123455566-090-3211231sdasdo" + newlines + "123" + newlines + "123"
- After running the script, the output file (b.docx) has identical content (no replacements)
- The replace count printed shows a non-zero number, indicating matches were found
- File permissions are normal; no Word dialogs are blocking
What I've tried:
- Using doc.SaveAs2() with FileFormat=16 (wdFormatDocx)
- Iterating through StoryRanges with NextStoryRange
- Including Shape.TextFrame replacement in headers/footers
- Closing the document without saving before SaveAs2
The Find.Execute() with Replace=2 (wdReplaceAll) appears to succeed, but the actual
Replacements are not persisted in the saved file.
How can I ensure the Find and Replace changes are actually saved?
Here is my code
import win32com.client from pathlib import Path def replace_text(input_file: str, output_file: str, search_text: str, replace_text: str) -> int: word = None doc = None try: word = win32com.client.Dispatch("Word.Application") word.Visible = False word.DisplayAlerts = False doc = word.Documents.Open(str(Path(input_file))) wd_find_continue = 1 wd_replace_all = 2 wd_format_docx = 16 total_replaced = 0 story = doc.StoryRanges(1) while story is not None: rng = story finder = rng.Find finder.ClearFormatting() finder.Text = search_text finder.Replacement.Text = replace_text finder.MatchCase = False finder.MatchWholeWord = False finder.MatchWildcards = False finder.MatchSoundsLike = False finder.MatchAllWordForms = False finder.Forward = True finder.Wrap = wd_find_continue occurrences = rng.Text.lower().count(search_text.lower()) if occurrences: finder.Execute(FindText=search_text, ReplaceWith=replace_text, Replace=wd_replace_all) total_replaced += occurrences story = story.NextStoryRange doc.SaveAs2(str(Path(output_file)), FileFormat=wd_format_docx) return total_replaced finally: if doc is not None: try: doc.Close(SaveChanges=False) except Exception: pass if word is not None: try: word.Quit() except Exception: pass def main(): input_file = r"E:\Document\\a.docx" output_file = r"E:\Document\\b.docx" search_text = "123" replace_text_value = "abc" count = replace_text(input_file, output_file, search_text, replace_text_value) print(f"count: {count}") if __name__ == "__main__": main()