Tristochi
Tristochi

Reputation: 1

Why are MailMerge objects unable to be converted to Unicode? Is there a reliable way to print templated docs in Python?

I am trying to read a text file which is formatted like a spreadsheet into a list, and then use the parameters from said columns as merge fields and insert them into a template word document using Python. However, I get a TypeError saying, "Objects of type 'MailMerge' can not be converted to Unicode when trying to print the docs using win32api.ShellExecute(). We normally do this process manually: sort the main text file into three others based on if the members are 15 days, 25 days, or 30 days delinquent, then use mail merge in word to select this text file as a list of recipients. I've written this code in the example as an aside from the main program to get the mechanics working before putting it together.

In the main program I have the sorting feature completed. I also was able to use document.merge() and insert information into one document. However to do this for several pages in one document I need to use MailMerge() and pass it dictionaries as arguments. I tried using a for loop with the respective row indices as values for the keys, but since that function needs more than one dictionary it did not work. I then came up with using a for loop to insert each member and their info into one merge, write it to the output file, print that output file, and do that for each member until it's done. I've tried using win32api.ShellExecute(0, "print", document, '/d:"%s"' % win32print.GetDefaultPrinter(), ".", 0) but get the error stated above. The only other print method I came across was converting it to a pdf but I don't want to lose the text and formatting of the document either.

from __future__ import print_function
from mailmerge import MailMerge
import os
import win32api
import win32print

# Formatting the list so that the indices match the columns in the text 
  doc.

text_file = open('J:\cpletters15.txt')
courtesy_pay_list = text_file.readlines()
text_file.close()
delimeted_text = [line.split('\t') for line in courtest_pay_list]

# Opening the template

template = 'J:\courtesy_pay_15_test.docx'
document = MailMerge(template)

# This should merge and then print each member on their own letter.

for row in delimeted_text[1:]:

    document.merge(
            SHARE_NBR = row[2],
            MEMBER_NBR = row[1], 
            CITY = row[11], 
            ADDRESS1 = row[9], 
            ADDRESS2 = row[10], 
            LAST_NAME = row[8], 
            STATE = row[12], 
            FIRST_NAME = row[7],
            ZIP = row[13],
            LETTER_DATE = row[4],
            BALANCE = row[6]
)
    document.write('J:\output.docx')
    win32api.ShellExecute(
        0, "print", document, '/d:"%s"' % win32print.GetDefaultPrinter(),
        ".", 0) 

I am expecting that this code should print each document after merging the fields, but instead I get the error "Objects of type 'MailMerge' can not be converted to Unicode."

(Sorry if this is too wordy I've never posted here before).

Upvotes: 0

Views: 694

Answers (1)

Tristochi
Tristochi

Reputation: 1

I eventually found in the source code for mailmerge.py that there is another function called merge_template that is supposed to replace mail_merge but this did not exist in the version I installed using pip. After consulting some python coders on Discord it proved to be better to make a list of dictionaries using the lines,

values = delimeted_text[1:]
header = delimeted_text[0]
my_Dict = ([{head:val for head, val in zip(header, val)} for val in values])

this was then accepted by merge_template and successfully printed as such:

document.merge_templates(big_Dict, 'nextPage_section')
document.write('J:\output.docx')
os.startfile('J:\\output.docx', 'print')

I ended up just overwriting the mailmerge.py with the source code from the link and then everything worked out.

Upvotes: 0

Related Questions