Recently, a civilian friend put forward an idea , Hope to achieve Automatically modify One of his Word Content . Because normally a project only needs to be modified Word Inside date , name , And some parameters , So I hope I can write a script for him , complete Word Automatically populates and generates new Word.
python3.8
pip install docx-mailmerge==0.5.0 # Used to deal with Word Fields set inside ( keyword ) Parse and populate
pip install python-docx==0.8.11 # For reading Word Paragraph of , Analyze, add, delete, modify and query the table
pip install pandas==1.4.2 # For reading Excel Tabular data
.
├── main.py # The main function
├── readme.md
├── req.txt # Environment package request
├── result
│ └── t.docx # Generated files
├── sources
│ ├── doc1.docx # Word Templates
│ └── input.csv # Defined key-value
$ python main.py # function
'''
1. Initialize object
2. Get the template object <- template_file_path
3. Read input csv file <- input_csv_path
4. Write data to objects
1. In template object key, Directly fill in csv Corresponding key data
2. In the template object date, according to csv Data filling in , And generate in sequence date_n_long Fill in the data
3. In the template object random, according to key Medium (a,b), Generate the corresponding random number , Fill in
5. Object preservation <- save_path
'''
import pandas as pd # pandas==1.4.2
from mailmerge import MailMerge # docx-mailmerge==0.5.0
import random
import re
from datetime import datetime
from dateutil.relativedelta import relativedelta
class WriteDocx():
def __init__(self,format_date='%Y.%m.%d'):
super().__init__()
self.doc = None
self.doc_key = None
self.dict_csv = {
}
self.format_date = format_date
def createTemplateDoc(self, template_file_path = "sources/doc1.docx"):
self.doc = MailMerge(template_file_path)
self.doc_key = self.doc.get_merge_fields()
print(" The keywords in the template include the following : ", self.doc_key)
print(" The template object is created , Start populating objects with data ...")
def getInputData(self, input_csv_path = "sources/input.csv"):
csv = pd.read_csv("sources/input.csv")
print(csv.head(2))
for i in range(len(csv["key"].values)):
self.dict_csv[csv.loc[i]["key"]] = csv.loc[i]["value"]
print(self.dict_csv)
# Analyze the scheme of generating random numbers
def getRandom(self, data = "random_2_6(1,3)")->list:
random_order = [eval(_) for _ in list(re.findall(r"(.*)\((.*),(.*)\)", data.split("_")[-1])[0])]
res_list = ["%0.2f"%random.uniform(random_order[1], random_order[2]) for i in range(random_order[0])]
return "[%s]"%",".join(res_list)
def getDate(self, date="2017.10.23", data = 'date_2-6'):
add_day = int(data.split("-")[-1]) # Added days
time_1 = datetime.strptime(date, "%Y.%m.%d") + relativedelta(days=add_day)
return datetime.strftime(time_1, '%Y.%m.%d') # Here is the final format
# Format date format
def format_date_(self, date):
time_1 = datetime.strptime(date, "%Y.%m.%d")
return datetime.strftime(time_1, self.format_date) # Here is the final format
def writeDoc(self, ):
# Generate doc_key in random and date The data of
# about random Generate corresponding data , about date Generate the corresponding delay
for _ in self.doc_key:
if "random" in _:
self.dict_csv[_] = self.getRandom(_) # random_2_2(0,3) --> [1.2, 0.5]
if "date" in _ and len(_.split("-"))==2: # '2017.10.23', 'date_2-6' --> 2017.10.29
self.dict_csv[_] = self.getDate(self.dict_csv[_.split("-")[0]], _)
if "date" in _: # Unified date format 2017.10.23->
self.dict_csv[_] = self.format_date_(self.dict_csv[_])
print(" The data to be populated is : ", self.dict_csv)
print(type(self.dict_csv))
self.doc.merge(** self.dict_csv) # Make a copy of Word file
def save(self, save_path = "result/t.docx"):
self.doc.write(save_path)
print(" The new file has been successfully saved to : ", save_path)
# Just change the position here
def main():
object = WriteDocx(format_date='%Y year %m month %d Japan ')
object.createTemplateDoc("sources/doc1.docx")
object.getInputData("sources/input.csv")
object.writeDoc()
object.save("result/t.docx")
if __name__=='__main__':
main()
Through this exercise , Let me find that civilian personnel can improve a lot of workflow . Just take the letter of introduction for each group transfer , All of them are written down by themselves , Such as name and other personal information , Where does the group relationship go from , Seal on the delivery . If according to the workflow of this article , Just count the above information of each person and save it to Excel Each column of , Make one Word Templates , You can generate a group transfer reference letter corresponding to everyone by column at one time , Print and stamp , There is no need to write by yourself , Assembly line operation is always more convenient and smooth than working separately . Last 2202 Years. , I hope that all comrades working in the civil service can have programming ideas , It may not be possible , But we can find a programming friend to improve the workflow , Improve work efficiency , Raise the happiness index !!!