Skip to main content

docx Mail Merge

PyPI

Performs a Mail Merge on Office Open XML (docx) files. Can be used on any system without having to install Microsoft Office Word. Supports Python 3.7 and up.

Installation

Installation with pip:

$ pip install docx-mailmerge2

Usage

Open the file.

from mailmerge import MailMerge
with MailMerge('input.docx') as document:
    ...

Open the file and setting options

from mailmerge import MailMerge, MailMergeOptions, OptionAutoUpdateFields, OptionKeepFields
mailmerge_options = MailMergeOptions(
    remove_empty_tables=False,
    auto_update_fields_on_open=OptionAutoUpdateFields.NO,
    keep_fields=OptionKeepFields.NONE,
    merge_if_fields=False,
    table_rows_replace_mode=False)
with MailMerge('input.docx', options=mailmerge_options) as document:
    ...

List all merge fields.

print(document.get_merge_fields())

Merge fields, supplied as kwargs.

document.merge(field1='docx Mail Merge',
               field2='Can be used for merging docx documents')

Merge table rows. In your template, add a MergeField to the row you would like to designate as template. Supply the name of this MergeField as anchor parameter. The second parameter contains the rows with key-value pairs for the MergeField replacements.

If the tables are empty and you want them removed, set remove_empty_tables=True in constructor.

document.merge_rows('col1',
                    [{'col1': 'Row 1, Column 1', 'col2': 'Row 1 Column 1'},
                     {'col1': 'Row 2, Column 1', 'col2': 'Row 2 Column 1'},
                     {'col1': 'Row 3, Column 1', 'col2': 'Row 3 Column 1'}])

The default behaviour is to expand the row containing the fields into several rows, one for each element in the data list. However, if you want to have a table with a fixed number of rows, you can set the option table_rows_replace_mode=True.

In the replace_mode the behaviour is to replace the table row containing the fields as well as the next rows with the data. If the table doesn’t have enough rows to contain all the data, an IndexError exception is thrown.

Starting in version 0.2.0 you can also combine these two separate calls into a single call to merge.

document.merge(field1='docx Mail Merge',
               col1=[
                   {'col1': 'A'},
                   {'col1': 'B'},
               ])

Starting in version 0.2.0 there’s also the feature for template merging. This creates a copy of the template for each item in the list, does a merge, and separates them by page or section breaks (see function documentation). Starting in version 0.8.0 you can also use fields in the headers/footers/footnotes with the merge_templates method.

document.merge_templates([
    {'field1': "Foo", 'field2: "Copy #1"},
    {'field1': "Bar", 'field2: "Copy #2"},
], separator='page_break')

Starting in version 0.6.0 the fields formatting is respected when compatible. Numeric, Text, Conditional and Date fields (0.6.2) are implemented. For Date fields a compatible datetime, date or time objects must be provided. If locale support is needed, make sure to call the setlocale before merging

import locale
locale.setlocale(locale.LC_TIME, '') # for system locale

document.merge_templates([
    {'datefield': datetime.date('2022-04-15')},
], separator='page_break')

The {NEXT} fields are supported (0.6.3).

You can also use the merge fields inside other fields, for example to insert pictures in the docx {INCLUDEPICTURE} or for conditional texts {IF}. Microsoft Word is needed to update the values of those fields.

{ INCLUDEPICTURE "{ MERGEFIELD path }/{ MERGEFIELD image }" }
{ IF "{ MERGEFIELD reason }" <> "" "Reason: { MERGEFIELD reason }" }

Always enclose the fields with double quotes, as the MERGE fields will be first filled in with data and then the other fields will be computed through Word.

If the fields are nested inside other fields, the outer fields need to be updated in Word. This can be done by selecting everything (CTRL-a) and then update the fields (F9). There is a way to force the Word to update fields automatically when opening the document. docx-mailmerge can set this setting when saving the document. You can configure this feature by using the auto_update_fields_on_open option. The value always will set the setting regardless if needed or not and the value auto will only set it when necessary (when nested fields exist). The default value no will not activate this setting.

The {NEXTIF} and {SKIPIF} fields are supported (0.9.0). The {IF} fields are supported (since version 0.9.0) in experimental mode only (merge_if_fields=True, see MailMergeOptions class).

The condition can use nested fields. Spaces are MANDATORY before and after the operator (<, <>, >, <=, >=, =). The values are better enclosed in double quotes. For <> and = operators, the Microsoft-style regular expressions are supported (?, *).

Write document to file. This should be a new file, as ZipFile cannot modify existing zip files.

document.write('output.docx')

By default, all MERGEFIELD fields are replaced with their value. If a value is not given, it is replaced with an empty string. If you want to keep the existing MERGEFIELD fields (with their current value) you can specify the keep_fields=”some” parameter in the constructor.

from mailmerge import MailMerge, MailMergeOptions, OptionKeepFields
with MailMerge('keep_unchanged_fields.docx',
        options=MailMergeOptions(
            keep_fields=OptionKeepFields.SOME)) as document:
    ...

If you want to only update the value of the MERGEFIELD fields but keep the fields themselves, you can specify the keep_fields=”all” parameter in the constructor. This way, you can change the document and update the fields again later.

from mailmerge import MailMerge, MailMergeOptions, OptionKeepFields
with MailMerge('keep_all_fields.docx',
        options=MailMergeOptions(
            keep_fields=OptionKeepFields.ALL)) as document:
    ...

How to populate Word Templates

There are two main sources of examples for template populating:

Generally, you have to create field code brackets in which expressions such as MERGEFIELD, IF and so on are inserted. Field code brackets looks like as curly brackets, but they are not ordinary curly brackets and must be created by special key shortcut or inserted as field. If you write curly brackets as oridnary text, they have not any special meaning.

Example of field code { MERGEFIELD reason }.

How to insert field code

Field code brackets or just field code can be inserted in the following ways:

  • by using keyboard shortcut CTRL-F9 (CMD-F9 on macOS) or,

  • by clicking Insert -> Field... -> <FieldName> in MS Word GUI

When you create field code by keyboard shortcut CTRL-F9, then select the field code and update it by pressing F9. Updating may result in hiding the raw field code. If you want to see the raw code again, you can toggle the display of field codes on and off using the ALT-F9 (OPTION-F9 on macOS) shortcut.

Inserting Dynamic Images

To include dynamic images in a docx template document you can use the { INCLUDEPICTURE “….” } field. For the path you can use MERGEFIELD dynamic fields. See example above.

The problem is to actually include the images in the word document after the mailmerge. This can be done by opening the merged docx in Microsoft Word, selecting all the text and pressing the F9 to update all fields. Unfortunately this method needs Microsoft Word installed and it is known to cause a lot of problems.

Another solution would be to use the docx-mergefields package to replace the INCLUDEPICTURE fields with the actual image. This method also works with images loaded from a database in base64 data-uri format, as well as URLs and local images.

See the documentation of docx-mergefields for examples.

Todo / Wish List

  • Better support for the IF fields and conditions

Contributing

  • Fork the repository on GitHub and start hacking

  • Create / fix the unit tests

  • Send a pull request with your changes

Unit tests

In order to make sure that the library performs the way it was designed, unit tests are used. When providing new features, or fixing bugs, there should be a unit test that demonstrates it. Run the test suite:

python -m unittest discover

Credits

This library was originally written by Bouke Haarsma and contributors.
This repository is maintained by Iulian Ciorăscu.

Release files for docx-mailmerge2 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for docx-mailmerge2 1.0.2
File Size Uploaded
docx_mailmerge2-1.0.2.tar.gz 36.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for docx-mailmerge2 1.0.2
File Interpreter ABI Platform
docx_mailmerge2-1.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 61.2 kB

Release files / docx_mailmerge2-1.0.2.tar.gz

Download URL docx_mailmerge2-1.0.2.tar.gz
Size 36.1 kB
Tags Source
SHA-256 checksum
How to use checksums
359ff18e236fa73c126e23c419d1f2640f33c2c457f0e3070d6bd3800e012dbf
BLAKE2b-256 checksum
How to use checksums
a9212fe2f67587cecdc3b710885bb46eb09a9dd7de0aa18dad1ae7710021811d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release files / docx_mailmerge2-1.0.2-py3-none-any.whl

Download URL docx_mailmerge2-1.0.2-py3-none-any.whl
Size 25.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eeba4acb85d3b692c011309d66c3298d9bd8209245b8a45513fa3299446ac7ea
BLAKE2b-256 checksum
How to use checksums
0c478ca087dd8be46f301da11fbb25390f7dea44062c956c555a0a167984a44b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page