1

I am trying to programmatically merge two Microsoft Word files:

enter image description here

and:

enter image description here

I wrote a program with python-docx:

from docx import Document
t1 = Document("test1.docx")
t2 = Document("test2.docx")
for p in t2.paragraphs:
    t1.add_paragraph(p.text,p.style)
t1.save("test1-new.docx")

I got this result:

enter image description here

As you can see, I got the text and the basic paragraph style, but lost the per-character style.

Is there any way to keep it?

vy32
  • 28,461
  • 37
  • 122
  • 246

2 Answers2

2

I ran a small test where I made a document like this:

hello

hello

hello

from docx import Document
t1 = Document("test.docx")

for p in t1.paragraphs:
    for run in p.runs:
        #print([method for method in dir(run.style)])
        print(run.font.bold, run.font.italic)

Returns:

None None
True None
True True

So if you put some more effort you can extract the Bold and Italic from the runs inside the paragraph.

Anton vBR
  • 18,287
  • 5
  • 40
  • 46
2

Here is working code:

#!/usr/bin/env python3.6

import os
import os.path
from docx import Document

def append_to_doc(doc,fname):
    t = Document(fname)
    for p in t.paragraphs:
        doc.add_paragraph("",p.style)       # add an empty paragraph in the matching style
        for r in p.runs:
            nr = doc.paragraphs[-1].add_run(r.text)
            nr.bold = r.bold
            nr.italic = r.italic
            nr.underline = r.underline


if __name__=="__main__":
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("--output",help="Output file")
    parser.add_argument("--template",help="Base file")
    parser.add_argument("files",nargs="+",help="Files to add")
    args = parser.parse_args()

    if not args.output:
        raise RuntimeError("--output required")
    if os.path.exists(args.output):
        raise RuntimeError(f"{args.output} exists")
    if not args.template:
        raise RuntimeError("--template required")


    doc = Document(args.template)
    for fname in args.files:
        append_to_doc(doc,fname)
    doc.save(args.output)
vy32
  • 28,461
  • 37
  • 122
  • 246