python 邮件合并项目中的空白数据字段

blank data field in python mailmerge project

我只是尝试在 python 中创建一个简单的邮件合并应用程序。所以我有两个文本文件。一个是名字,另一个是位置。 名字是:

Aang
Zuko
Appa
Katara
Sokka
Momo
Uncle Iroh
Toph
Brian
Toby
Donna
Petra Verkaik
Ava Price

在另一个文件名中 invited_places.txt。我有以下内容:

Bristol
London
Plymouth
Cardiff
Swansea
Glasgow
Belfast
Twickenham
New York
New Orleans
Paris
Bridgend
Manchester

所以我可以使它更有活力这就是我写的。

PLACEHOLDER = "[name]"
ADDRESS = "[place]"
 
with open("./Input/Names/invited_names.txt") as names_files:
    names = names_files.readlines()
    # print(names)
with open("./Input/Places/invited_places.txt") as places_files:
    places = places_files.readlines()
    # print(places)
 
with open("./Input/Letters/starting_letter.txt") as letter_file:
    letter_contents = letter_file.read()
 
    for name in names:
        stripped_name = name.strip()
        new_letter = letter_contents.replace(PLACEHOLDER, stripped_name)
 
        for place in places:
            stripped_place = place.strip()
            new_letter = letter_contents.replace(ADDRESS, stripped_place)
            
        with open(f"./Output/ReadyToSend/letter_for_{stripped_name}.txt",mode="w") as completed_letter:
            completed_letter.write(new_letter)

不幸的是,当字母打印出来时,我只得到了地名。

亲爱的[姓名],

本周六邀请你参加我的生日。感谢来自曼彻斯特的旅行

希望你能成功!

布莱恩

不确定是否更好的解决方案是使用字典。任何帮助将不胜感激。

首先,您的所有收件人总是从曼彻斯特出发;这是因为您的位置列表针对每个收件人姓名进行了完整循环,并且文档在循环后保存。

收件人姓名从地名切换,但是当您在第二个for循环中分配地址时,您使用的是原始字母模板而不是应用名称时修改的模板,[=的分配11=]替换为原来的letter_contents.

这可以通过交换来解决:

new_letter = letter_contents.replace(ADDRESS, stripped_place)

new_letter = new_letter.replace(ADDRESS, stripped_place)

你用字典代替列表的想法很好。在处理了无数邮件合并项目之后,最困难和必要的问题之一就是确保所有客户详细信息始终保持同步。我会给每个收件人分配一个唯一的 ID 来绑定数据。在开始处理大数据集和大量字段时,将两个数据字段读入同一个键下的字典中会更容易。

这方面的一个例子,使用 defaultDict:

from collections import defaultdict

PLACEHOLDER = "[name]"
ADDRESS = "[place]"

fieldMapper = defaultdict(dict)


with open("invited_names.txt") as names_files:
    names = names_files.readlines()

with open("invited_places.txt") as places_files:
    places = places_files.readlines()

 
with open("starting_letter.txt") as letter_file:
    letter_contents = letter_file.read()
    docID = 0 # create a document ID
    for name in names:
        stripped_name = name.strip()
        fieldMapper[docID]['name']=stripped_name
        docID +=1
        
    docID = 0
    for place in places:
        stripped_place = place.strip()
        fieldMapper[docID]['address']=stripped_place
        docID +=1

    for document,fields in fieldMapper.items(): # run through each recipient / Doc ID in dictionary
        new_letter = letter_contents.replace(ADDRESS, fields.get('address'))
        new_letter = new_letter.replace(PLACEHOLDER, fields.get('name'))
        
        with open(f"letter_for_{fields.get('name')}.txt",mode="w") as completed_letter:
            completed_letter.write(new_letter)

如果可能的话,我会为您的源数据增加弹性,以使其难以混淆收件人信息的不同字段。事实上,如果在您的数据中途输入了一个空行,任何进一步的数据都将不同步。这可以通过使用一个包含逗号分隔值(或任何其他分隔符)的源数据文件来实现,或者在 both 文本文件中使用分隔的收件人 ID 以确保始终保留客户记录同步中。 Reading CSV files in Python