Install
openclaw skills install @winezzz999/word-template-fillerFill and edit Word .docx templates on Windows via win32com, preserving all formatting, images, underlines, page breaks, and table layouts using Word automation.
openclaw skills install @winezzz999/word-template-fillerFill/edit Word .docx templates on Windows via win32com COM automation — preserves ALL formatting, images, underlines, page breaks, and table layout. Combines template-filling precision with general-purpose document automation.
| Approach | Format/Image Preservation | Requires Word |
|---|---|---|
| win32com (this skill) | ✅ 100% — Word does the work | ✅ Yes |
python-docx | ❌ Drops images, corrupts complex formatting | ❌ No |
docxtpl (Jinja) | ⚠️ Better than python-docx, still risks layout drift | ❌ No |
pip install pywin32)shutil.copy2() before modifying. Never touch the original.doc.Range().Text = ...: Destroys all formatting, images, tables. Use targeted Find/Replace instead.InsertBefore for blank fields: Insert text before the para mark to preserve character-level formatting (underlined spaces).\f characters. Never replace a paragraph that contains \f.Templates often use underlined spaces (空格 + underline=1) for fill-in lines. Insert the value before the spaces:
def fill_cover_field(doc, label_text, value):
for p in doc.Paragraphs:
txt = p.Range.Text
if txt.startswith(label_text):
colon_pos = txt.find(':')
if colon_pos > 0:
rng = p.Range.Duplicate
insert_at = rng.Start + colon_pos + 1
after_rng = rng.Duplicate
after_rng.Start = insert_at
if value:
after_rng.InsertBefore(value)
return True
return False
def append_answer(cell, question_text, answer_text):
rng = cell.Range.Duplicate
f = rng.Find
f.Text = question_text
f.MatchCase = True
f.Forward = True
f.Wrap = 1 # wdFindStop
if f.Execute():
found = f.Parent
found.MoveEnd(1, -1) # exclude para mark
found.Text = question_text + '\n' + answer_text
return True
return False
⚠️ Always verify for double punctuation (。?, !?) after using this.
For sub-tables within cells (序号/名称/功能), fill blank paragraphs by index:
def insert_into_blank_para(cell, para_1b, text):
paras = cell.Range.Paragraphs
if para_1b <= paras.Count:
p = paras(para_1b)
p.Range.InsertBefore(text)
Always analyze cell structure first:
def debug_cell(cell):
paras = cell.Range.Paragraphs
for i in range(paras.Count):
txt = repr(paras(i+1).Range.Text)
print(f" Para {i}: {txt}")
Add a page break before a heading:
for p in doc.Paragraphs:
if 'C2.转向架' in p.Range.Text:
rng = p.Range.Duplicate
rng.Collapse(1) # start of range
rng.InsertBefore('\f')
break
def find_replace(doc, find_text, replace_text):
rng = doc.Range()
f = rng.Find
f.Text = find_text
f.MatchCase = True
f.Forward = True
f.Wrap = 2 # wdFindContinue
f.Replacement.Text = replace_text
f.Execute(Replace=2) # wdReplaceAll
def insert_at(doc, text, where='end'):
rng = doc.Range()
if where == 'start':
rng.Collapse(1)
else:
rng.Collapse(0)
rng.InsertBefore(text + '\n')
def set_header_footer(doc, header_text='', footer_text=''):
for section in doc.Sections:
if header_text:
header = section.Headers(1)
header.Range.Text = header_text
if footer_text:
footer = section.Footers(1)
footer.Range.Text = footer_text
def add_image(doc, image_path, width=100):
rng = doc.Range()
rng.Collapse(0)
inline_shape = rng.InlineShapes.AddPicture(image_path)
inline_shape.Width = width
inline_shape.Height = width * 0.75
def merge_docs(input_paths, output_path):
merged = word.Documents.Add()
for path in input_paths:
merged.Range().InsertFile(path)
merged.SaveAs(output_path)
merged.Close()
def export_to_pdf(doc_path, output_path):
doc = word.Documents.Open(doc_path)
doc.SaveAs(output_path, FileFormat=17) # wdFormatPDF
doc.Close()
\f characters at correct positions。?, !? patternsWINWORD.EXE between runs: taskkill /f /im WINWORD.EXE.Duplicate on ranges to avoid mutation side-effects| Don't Do | Why |
|---|---|
doc.Range().Text = ... | Destroys ALL formatting, images, tables |
Replace paragraph containing \f | Loses page break |
python-docx to save modified template | Loses images, complex formatting |
\n in Word Find patterns | Word uses \r (chr 13) for paragraph marks |
| Blindly replace cover paragraph text | Destroys underlined spaces |
Forget to verify after append_answer | Leaves extra ? behind |