Skip to main content

Replace words inside a Word document without losing format

Project description

python-docx-replace


This library was built on top of python-docx and the main purpose is to replace words inside a document without losing the format.

Let's explain the process behind the library:

First way, losing formatting

One of the ways to replace a key inside a document is by doing something like the code below. Can you do this? YES! But you are going to lose all the paragraph formatting.

key = "${name}"
value = "Ivan"
for p in _get_all_paragraphs(doc):
    if key in p.text:
        p.text = p.text.replace(key, value)

Second way, not all keys

Using the python-docx library, each paragraph has a couple of runs which is a proxy for objects wrapping <w:r> element. We are going to tell more about it later and you can see more details in the docs.

You can try replacing the text inside the runs and if it works, then your job is done:

key = "${name}"
value = "Ivan"
for p in _get_all_paragraphs(doc):
    for run in p.runs:
        if key in run.text:
            run.text = run.text.replace(key, value)

The problem here is that the key can be broken in more than one run, and then you won't be able to replace it, for example:

It's going to work:

Word Paragraph: "Hello ${name}, welcome!"
Run1: "Hello ${name}, w"
Run2: "elcome!"

It's NOT going to work:

Word Paragraph: "Hello ${name}, welcome!"
Run1: "Hello ${na"
Run2: "me}, welcome!"

You are probably wondering, why does it break paragraph text this way? What are the purpose of the run?

Imagine a Word document with this format:

word

Considering this, what would the format be after parsing the key? Highlighted yellow? Bold and underline? Red with another font? All of them?

That's the purpose of runs, each run hides their sets.

The final format will be the format that is present in the $ character. All of the others key's characters and their formats will be discarded. In the example above, the final format will be highlighted yellow.

Solution

The solution adopted is quite simple. First we try to replace in the simplest way, as in the previous example. If it's work, great, all done! If it's not, we build a table of indexes:

key = "${name}"
value = "Ivan"

Word Paragraph: "Hello ${name}, welcome!"
Run1: "Hello ${na"
Run2: "me}, welcome!"

Word Paragraph: 'H' 'e' 'l' 'l' 'o' ' ' '$' '{' 'n' 'a' 'm' 'e' '}' ',' ' ' 'w' 'e' 'l' 'c' 'o' 'm' 'e' '!'
Char Indexes:    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20  21  22
Run Index:       0   0   0   0   0   0   0   0   0   0   1   1   1   1   1   1   1   1   1   1   1   1   1
Run Char Index:  0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   10  11  12

Here we have the char indexes, the index of each run by char index and the run char index by run. A little confusing, right? 

With this table we can process and replace all the keys, getting the result:

# REPLACE PROCESS:
Char Index 6 = p.runs[0].text = "Ivan"  # replace '$' by the value
Char Index 7 = p.runs[0].text = ""  # clean all the others parts
Char Index 8 = p.runs[0].text = ""
Char Index 9 = p.runs[0].text = ""
Char Index 10 = p.runs[1].text = ""
Char Index 11 = p.runs[1].text = ""
Char Index 12 = p.runs[1].text = ""

After that, we are going to have:

Word Paragraph: 'H' 'e' 'l' 'l' 'o' ' ' 'Ivan' '' '' '' '' '' '' ',' ' ' 'w' 'e' 'l' 'c' 'o' 'm' 'e' '!'
Indexes:         0   1   2   3   4   5   6      7  8  9 10 11 12  13  14  15  16  17  18  19  20  21  22
Run Index:       0   0   0   0   0   0   0      0  0  0 1  1  1   1   1   1   1   1   1   1   1   1   1
Run Char Index:  0   1   2   3   4   5   6      7  8  9 0  1  2   3   4   5   6   7   8   9   10  11  12

All done, now you Word document is fully replaced keeping all the format.

How to use

Via PyPI

pip3 install python-docx-replace

Vanilla

Grab the docx_replace.py file from the src folder and be happy!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python-docx-replace-0.0.4.tar.gz (4.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

python_docx_replace-0.0.4-py3-none-any.whl (5.3 kB view details)

Uploaded Python 3

File details

Details for the file python-docx-replace-0.0.4.tar.gz.

File metadata

  • Download URL: python-docx-replace-0.0.4.tar.gz
  • Upload date:
  • Size: 4.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.12

File hashes

Hashes for python-docx-replace-0.0.4.tar.gz
Algorithm Hash digest
SHA256 882659b00778ed074c11b06fc960d1c9443763f42910f6485e83ee594c129742
MD5 3ce4bbf2e890faaac0600ac27238ddcd
BLAKE2b-256 d7664d2e4e2e95f86231fa9bb0542107f3af7bab49ad1d043a3f3bc00d466ac7

See more details on using hashes here.

File details

Details for the file python_docx_replace-0.0.4-py3-none-any.whl.

File metadata

File hashes

Hashes for python_docx_replace-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 f77cf5e9575adaafe87021b67142468e7cb1212c5e5a5066fa9cee1ab4c7a1ce
MD5 f7f1d0121864b872a173822e9376eb73
BLAKE2b-256 8c2ae90c2ff9a84ce0dc4c87dd4a960d2a0c4764b1ab02daffb2b50ccf9878ed

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page