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
我只是尝试在 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