def generate(): target = os.path.join(APP_ROOT, 'static/') for template in request.files.getlist("file"): print(template) filename = template.filename document = MailMerge(template) print(document.get_merge_fields()) {'name', 'address', 'serial', 'number', 'issued'} cur = mysql.connection.cursor() if request.method == 'POST': id = request.form['id'] cur.execute("SELECT * FROM users where id = %s", [id]) result = cur.fetchall() for user in result: name = user[1] address = user[2] serial = user[3] number = user[4] issued = user[5] document.merge(name=user[1], date='{:%d-%m-%Y}'.format(datetime.now()), address=user[2], serial=user[3], number=user[4], issued=user[5]) document.write('static/test.docx') return render_template("complete.html")
def report(self): if not fileName1: return template = "RSM-RLT(A)钢筋笼长度检测报告.docx" document_1 = MailMerge(template) document_1.merge( project_name=self.ProjectName, construct_institution=self.ConstrucInstitution, test_institution=self.TestInstitution, tester_name=self.TesterName, test_date=self.TestDate, ) #document_1.add_picture # document_1.add_picture('test_zdata.png') document_1.write('file.docx') doc = Document('file.docx') self.savepicture() run = doc.tables[2].cell(0, 0).paragraphs[0].add_run() run.add_picture('test_zdata.png', width=Inches(5.0)) run = doc.tables[2].cell(1, 0).paragraphs[0].add_run() run.add_picture('test_hdata.png', width=Inches(5.0)) run = doc.tables[2].cell(2, 0).paragraphs[0].add_run() run.add_picture('test_bdata.png', width=Inches(5.0)) run = doc.tables[2].cell(3, 0).paragraphs[0].add_run() run.add_picture('test_pitch.png', width=Inches(5.0)) run = doc.tables[2].cell(4, 0).paragraphs[0].add_run() run.add_picture('test_roll.png', width=Inches(5.0)) run = doc.tables[2].cell(5, 0).paragraphs[0].add_run() run.add_picture('test_heading.png', width=Inches(5.0)) fileName2, ok2 = QFileDialog.getSaveFileName(self, "文件保存", "C:/", "Word Files (*.docx)") if fileName2: doc.save(fileName2)
def hardware_list(): template = "Leihgeräte1.docx" document = MailMerge(template) myList = [] myList1 = [] counter = 0 for i in list1.curselection(): counter = counter + 1 switches = round(counter * 1 / 5) cable = int(counter + 2 + switches) c = str(counter) s = str(switches) x = str(cable) document.merge(Bam=bam_text.get(), Laptops=c, Netzteile=c, Kabel=x, Maus=c, Switches=s, Steckdosen=s, Date=time.strftime("%d.%m.%Y")) document.write('test1.docx') os.system('start test1.docx')
def tenant_bills_to_docx(self): """ Compose a single bill for a tenant_id, save it to disk. returns a string containing the path to the saved file. """ for t in self.rtp.tenantBillList: if not self.rtp.bill_tenant_0: if t.tenant_id == 0: continue t_bill = MailMerge(self.rtp.pdf_docx_template) t_bill.merge( name=format_values(t.tenant_name), month_year=format_values("{} {}".format( self.rtp.month_str, self.rtp.year)), total=format_values(t.charge_total), date=format_values( datetime.datetime.now().strftime('%Y %B %d')), room_rate=format_values(t.charge_room), gas=format_values(t.charge_gas), internet=format_values(t.charge_internet), electricity=format_values(t.charge_electricity), recurring=format_values(t.charge_recurring), other=format_values(t.charge_other), memo_gas=format_values(t.memo_gas), memo_internet=format_values(t.memo_internet), memo_electricity=format_values(t.memo_electricity), memo_recurring=format_values(t.memo_other), memo_other=format_values(t.memo_other), ) docx = self.rtp.google_path + "bills\\" + self.__format_file_name( t, "docx") if isfile(docx): remove(docx) t_bill.write(docx) t.docx_long_name = docx self.logger.debug("Created docx_long_name file: {}".format(docx))
def mail_merge(self, company_name): #template1 = 'test1.docx' template2 = 'Executive_Summary2.docx' document = MailMerge(template2) print (document.get_merge_fields()) #merge fields #{'ZIP_Code', 'Address_Line_2', 'Country_or_Region', #'Address_Line_1', 'Company_Name', 'Title', # 'State', 'City', 'First_Name', 'Work_Phone', #'Email_Address', 'Home_Phone', 'Last_Name'} document.merge(Title = 'Mr', First_Name ='Joe', Last_Name = 'OShea', Company_Name = 'Principal Systems', Email_Address= '*****@*****.**', City = 'Dublin', State = 'Dublin', Work_Phone ='123333', Address_Line_1 ='56 Pembrooke road', Address_Line_2='Ballsbridge', Home_Phone='1234567', Country_or_Region='Ireland', ZIP_Code = 'Dublin6') output = company_name + '_output.docx' document.write(output) return output
def appointment_letter(mediator, medAddress, medCityStateZip, medEmail, medPhone, mhp, medNum, petitioner, petContact): name = HumanName(mediator) titleLast = name.title + " " + name.last scriptDir = os.path.dirname("mediation.py") relPath = "letter_templates/AppointmentLetterTemplate.docx" appointmentFilePath = os.path.join(scriptDir, relPath) document = MailMerge(appointmentFilePath) document.merge( mediator=mediator, medAddress=medAddress if medAddress != "N/A" else "", medCityStateZip=medCityStateZip if medCityStateZip != "N/A" else "", medEmail=medEmail, medPhone=medPhone, mhp=mhp, medNum=str(medNum), titleLast=titleLast, petitioner=petitioner, petContact=petContact) docName = mhp.replace(" ", "") + "AppointmentLetter" + str(medNum) + ".docx" relPath = "output_files/" + docName outputFilePath = os.path.join(scriptDir, relPath) document.write(outputFilePath) create_pdf(outputFilePath) print "\nAn appointment letter has been created!\n"
def invoice(address, invoice_type, cost_per_head, number_of_guests, band_name, band_cost, number_of_days, guests_cost, cost_per_day, sub_total, vat, total, file_name): """uses template to mail-merge an invoice""" try: template = "M:\GitHub\Hotel-Booking-System-training\Test\Invoice\invoiceTemplate.docx" document = MailMerge(template) document.merge( GuestsCost=str(guests_cost), costPerHead=str(cost_per_head), BandCost=str(band_cost), Date=str(datetime.datetime.now().date()), VAT=str(vat), Address=str(address), BandName=str(band_name), subTotal=str(sub_total), TotalCost=str(total), CostPerDay=str(cost_per_day), numberofguests=str(number_of_guests), InvoiceType=str(invoice_type), numberofDays=str(number_of_days) ) if file_name: document.write(file_name) except Exception as e: print(e)
def generate_report(output_path, PIPELINE_ROOT, merge_values): ''' Generate a report by mail merging merge_values into Phage_Genomics_Report_Template.docx :param output_path: Full file path to output report (ex. foo/bar/reportname.docx) :param merge_values: Values to merge into template. Open template to see fields. ''' # Create a document from template template = os.path.join(PIPELINE_ROOT, 'Phage_Genomics_Report_Template.docx') document = MailMerge(template) # Convert all values to formatted strings for key in merge_values.keys(): if type(merge_values[key]) == int: merge_values[key] = '{:,}'.format(merge_values[key]) elif type(merge_values[key]) == float: merge_values[key] = '{:,.2f}'.format(merge_values[key]) else: merge_values[key] = str(merge_values[key]) # Add collected values to template document.merge(**merge_values) # Save document document.write(output_path)
def makeReport(self, db, template): for rule_key in db.keys(): print(rule_key) for did in db[rule_key].keys(): document = MailMerge(template) print(did) dr_list = [] i = 1 for item in db[rule_key][did]: d = {} d['ListNo'] = str(i) d['FileName'] = item[1] d['FileLine'] = str(item[2]) t = catex.catex(d['FileName']) d['FileContent'] = t.catex(item[2], 1, 1) t.close() dr_list.append(d) i = i + 1 document.merge(DR_Rule_Title=rule_key, DR_Rule_Category=did, DR_Reviewer=self._reviewer, DR_Approver=self._approver, DR_Writer=self._writer) document.merge_rows("ListNo", dr_list) document.write("result_%s.docx" % (rule_key + did)) document.close()
def mail_merge(self, template, kwargs): company_name = kwargs.get('Company_Name', "default company_name") print('******',company_name) print('*******************', kwargs.items()) document = MailMerge(template) print (document.get_merge_fields()) #merge fields #{'ZIP_Code', 'Address_Line_2', 'Country_or_Region', #'Address_Line_1', 'Company_Name', 'Title', # 'State', 'City', 'First_Name', 'Work_Phone', #'Email_Address', 'Home_Phone', 'Last_Name'} document.merge(Title=kwargs.get('Title', "default title"), First_Name=kwargs.get('First_Name', "default fname"), Last_Name=kwargs.get('Last_Name', "default lname"), Company_Name=kwargs.get('Company_Name', "default company_name"), Email_Address=kwargs.get('Email_Address', "default email"), City=kwargs.get('City', "default city"), State=kwargs.get('State', "default state"), Work_Phone=kwargs.get('Work_Phone', "default Work Phone"), Address_Line_1=kwargs.get('Address_Line_1', "Address_Line_1"), Address_Line_2=kwargs.get('Address_Line_2', "default Address_Line_2"), Home_Phone=kwargs.get('Home_Phone', "Home_Phone"), Country_or_Region=kwargs.get('Country_or_Region', "default Country_or_Region"), ZIP_Code=kwargs.get('ZIP_Code ', "default ZIP_Code ")) output = company_name + '_output.docx' document.write(output) print(output, ' is ready') return output
def test(self): document = MailMerge( path.join(path.dirname(__file__), 'test_macword2011.docx')) self.assertEqual( document.get_merge_fields(), set([ 'first_name', 'last_name', 'country', 'state', 'postal_code', 'date', 'address_line', 'city' ])) document.merge(first_name='Bouke', last_name='Haarsma', country='The Netherlands', state=None, postal_code='9723 ZA', city='Groningen', address_line='Helperpark 278d', date='May 22nd, 2013') with tempfile.TemporaryFile() as outfile: document.write(outfile) expected_tree = etree.fromstring( '<w:document xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" ' 'xmlns:ns1="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w="http://schemas' '.openxmlformats.org/wordprocessingml/2006/main" mc:Ignorable="w14 wp14">' '<w:body><w:p ns1:paraId="25CDEC86" ns1:textId="77777777" ' 'w:rsidR="00FB567A" w:rsidRDefault="00541684"><w:r><w:t>Bouke</w:t></w:r><w:r w:rsidR="00916690"><w:t ' 'xml:space="preserve"> </w:t></w:r><w:r><w:t>Haarsma</w:t></w:r></w:p><w:p ns1:paraId="67F7A559" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00541684"><w:r><w:t>Helperpark ' '278d</w:t></w:r></w:p><w:p ns1:paraId="228F2AEA" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00541684"><w:r><w:t>9723 ZA</w:t></w:r><w:r><w:t xml:space="preserve"> ' '</w:t></w:r><w:r><w:t>Groningen</w:t></w:r><w:bookmarkStart w:id="0" w:name="_GoBack" /><w:bookmarkEnd ' 'w:id="0" /><w:r w:rsidR="00916690"><w:t xml:space="preserve"> </w:t></w:r><w:r><w:t /></w:r><w:r ' 'w:rsidR="00916690"><w:t xml:space="preserve"> </w:t></w:r><w:r><w:t>The ' 'Netherlands</w:t></w:r></w:p><w:p ns1:paraId="696E15D7" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690" /><w:p ns1:paraId="3F48DA35" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690" /><w:p ns1:paraId="68E7FBD1" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690"><w:r><w:t xml:space="preserve">Groningen, </w:t></w:r><w:r><w:t>May 22nd, ' '2013</w:t></w:r><w:r><w:t>,</w:t></w:r></w:p><w:p ns1:paraId="26B47597" ns1:textId="77777777" ' 'w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="740FF493" ns1:textId="77777777" ' 'w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="232699A0" ns1:textId="77777777" ' 'w:rsidR="00916690" w:rsidRDefault="00916690"><w:r><w:t xml:space="preserve">Dear ' '</w:t></w:r><w:r><w:t>Bouke</w:t></w:r><w:r><w:t>,</w:t></w:r></w:p><w:p ns1:paraId="1AE04A19" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="298752B0" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="477BE6DB" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690"><w:r><w:t>I hope this message finds ' 'you well.</w:t></w:r></w:p><w:p ns1:paraId="77542CE2" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690" /><w:p ns1:paraId="734AC552" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690" /><w:p ns1:paraId="1680D84C" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690"><w:r><w:t>Kind regards,</w:t></w:r></w:p><w:p ns1:paraId="67F698AC" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="7A4C001B" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690"><w:r><w:t>docx-mailmerge' '.</w:t></w:r></w:p><w:sectPr w:rsidR="00916690" w:rsidSect="00CA5A66"><w:pgSz w:h="16840" w:w="11900" ' '/><w:pgMar w:bottom="1417" w:footer="708" w:gutter="0" w:header="708" w:left="1417" w:right="1417" ' 'w:top="1417" /><w:cols w:space="708" /><w:docGrid w:linePitch="360" /></w:sectPr></w:body></w:document>' ) self.assert_equal_tree(expected_tree, list(document.parts.values())[0].getroot())
def save_worklog(): """Create and save the worklog""" def row_to_dict(row): d = { 'Date': str(row.Date.day), 'Hours': str(row.Hours), 'Description': row.Comments, 'Task': '' } return d template = r'../templates/worklog_template.docx' document = MailMerge(template) # Fill the header document.merge( Name=name, Year=year, Month=month, Total_hours=str(total_hours), ) # Fill the table # print(f"IRAP df hours: {irap_df.Hours}") irap_df.Hours = irap_df.Hours.replace(np.nan, 0) table_dict = irap_df.replace(np.nan, '').apply(row_to_dict, axis=1) document.merge_rows('Date', table_dict) file_name = f"{name} {month} {year} IRAP Worklog.docx" document.write(file_name) st.markdown(get_binary_file_downloader(file_name, file_name), unsafe_allow_html=True) document.close() print(f"Worklog save successful.")
def get(self, request, *args, **kwargs): username = request.session.get("username") user = Commentuser.objects.get(username=username) ins = Commentuser.objects.get(username=user.username).ins forn = FornPro.objects.get(ins_nm=ins.ins_nm) apply_ins = ApplyInfo.objects.get(ins=ins) if apply_ins.first_access == 1: fs = "■" sn = "□" else: fs = "□" sn = "▣" if apply_ins.net_ty == 0: net_ty_1 = "√" net_ty_2 = "×" else: net_ty_2 = "√" net_ty_1 = "×" # 打印模板 path = "media/upload/apply_temp/申请信息模板.docx" # 创建邮件合并文档并查看所有字段 document_1 = MailMerge(path) document_1.merge(ins_nm=ins.ins_nm, contact_nm=apply_ins.contact_nm, phone=apply_ins.phone, email=apply_ins.email, bank_num=apply_ins.bank_num, test_num=apply_ins.test_num, production_ccpc=apply_ins.production_ccpc, soft_nm=apply_ins.soft_nm, soft_type=apply_ins.soft_type, mid_message=apply_ins.mid_message, mid_apply=apply_ins.mid_apply, pro_version=forn.pro_version, pro_system=forn.pro_system, fs=fs, sn=sn, ins_mid=apply_ins.mid_message, net_ty_1=net_ty_1, net_ty_2=net_ty_2, access_obj=apply_ins.access_obj, start_time=apply_ins.start_time.strftime("%Y-%m-%d"), end_time=apply_ins.end_time.strftime("%Y-%m-%d")) target = 'media/upload/apply_info/' raw_name = ins.ins_nm + ".docx" if not os.path.exists(os.path.dirname(target)): os.makedirs(target) file_path = os.path.join(target, raw_name) document_1.write(file_path) file = open(file_path, 'rb') response = FileResponse(file) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename=' + raw_name return response
def document(): content = request.json data_entries = [] for i,j,l,m,n in zip(content['data'],content['hours'],content['goals'],content['description'],content['hoursFrequncy']): x={} x['SupportCategory'] = i['SupportCategoryName'] x['ItemName'] = i['SupportItemName'] x['ItemId'] = i['SupportItemNumber'] multiplication = "" if (n[-1]=="W"): x['H'] = "Hours per Week "+ n.split(',')[0] + "\n" + "Duration " + n.split(',')[1] multiplication = n.split(',')[0] + " x " + n.split(',')[1] + "x" elif (n[-1]=="M"): x['H'] = "Hours per Month "+ n.split(',')[0] + "\n" + "Duration " + n.split(',')[1] multiplication = n.split(',')[0] + " x " + n.split(',')[1] + "x" else: x['H'] = "Hours "+ n multiplication = n + " x " x['Cost'] = multiplication + str(i['Price']) + "\n"+"\n" + str(i['Price']*int(j)) x['Description'] = str(m) goals = "" for goal in l: goals = goals + goal + "\n" + "\n" x['Goals'] = goals data_entries.append(x) document = MailMerge('WordTemplate.docx') document.merge(name=str(content['name']),ndis=str(content['ndis']),sos=str(content['sos']),duration=str(int(content['duration']/7))+" Weeks",start=content['start'],end=content['end'],today=content['today'],policy=content['policy']) document.merge_rows('SupportCategory',data_entries) document.write('test-output.docx') return send_file('test-output.docx', as_attachment=True)
def function(): #获得参数 # SimulationTime_get = str(inp1.get()) # dt_get = str(inp2.get()) # compressed_get = str(inp3.get()) constraints_get = str(comb.get()) rcoulomb_get = str(inp5.get()) rvdw_get = str(inp5.get()) tc_get = str(inp7.get()) tau_get = str(inp8.get()) ref_get = str(inp9.get()) gen_temp_get = str(inp10.get()) #作一步计算 #加载模板 template = "./model/NVTmdp.docx" document = MailMerge(template) print("Fields included in {}: {}".format(template, document.get_merge_fields())) document.merge( constraints=constraints_get, #这个要看模型 rcoulomb=rcoulomb_get, #这个为cutoff 参数值。rvdw是LJ或buckingham的阈值。默认为1.0 nm rvdw=rvdw_get, #这个为cutoff 参数值。rvdw是LJ或buckingham的阈值。默认为1.0 nm tc_grps=tc_get, #这个是温度热浴的分组 tau_t=tau_get, #只是增加或减少组别数 ref_t=ref_get, #这个是改温度的。单位是开氏温度K。(分组要对应好,tau_t有两个0.1就是两个组,ref_t也要两个组。) gen_temp=gen_temp_get #这个温度要于ref_t对应 ) document.write('NVT-MdpOut.docx') path = "NVT-MdpOut.docx" doc = Document(path) print("----------生成模板中-----------") #批量写入到mdp中 with open("NVT-MdpOut.mdp", "w") as file: for paragraph in doc.paragraphs: print(paragraph.text) file.write(paragraph.text + "\n") #别嘴臭我,我真的只会if和else........ # answer = tkinter.messagebox.askokcancel('消息', '模板文件生成成功') # if nsteps_get == '': # answer = tkinter.messagebox.askokcancel('警告', 'nsteps没有填写') # if dt_get == '': # answer = tkinter.messagebox.askokcancel('警告', 'dt没有填写') # if compressed_get == '': # answer = tkinter.messagebox.askokcancel('警告', 'compressed没有填写') if constraints_get == '': answer = tkinter.messagebox.askokcancel('警告', 'constraints没有填写') if rcoulomb_get == '': answer = tkinter.messagebox.askokcancel('警告', 'rcoulomb没有填写') if rvdw_get == '': answer = tkinter.messagebox.askokcancel('警告', 'rvdw没有填写') if tc_get == '': answer = tkinter.messagebox.askokcancel('警告', 'tc-grps没有填写') if tau_get == '': answer = tkinter.messagebox.askokcancel('警告', 'tau-t没有填写') if ref_get == '': answer = tkinter.messagebox.askokcancel('警告', 'ref-t没有填写') if gen_temp_get == '': answer = tkinter.messagebox.askokcancel('警告', 'gen_temp没有填写') else: answer = tkinter.messagebox.askokcancel('消息', '模板文件生成成功')
class LetterModel: def __init__(self): self.templateFile = "AppData/Templates/Letter.docx" self.document = MailMerge(self.templateFile) self.toFileName = "User Data/" def saveLetterInfo(self, letter: Letters): date = datetime.datetime.today().strftime("%d/%b/%Y") self.document.merge(date=date, bank_name=letter.getBankName(), branch_address=letter.getAddress(), inv_id=str(letter.getComplaintNo()), subject_line=letter.getSubjectLine(), body=letter.getLetterContent()) year = datetime.datetime.now().strftime("%Y") month = datetime.datetime.now().strftime("%B") # saveFilePath = self.toFileName+month+"_"+year+"/"+"LETTERS AND REPORTS/"+ saveFilePath = self.toFileName+month+"_"+year+"/"+"LETTERS AND REPORTS/" + \ str(letter.getComplaintNo())+" " + \ letter.getAddress()+" Branch, "+letter.getZone()+" Zone." self.saveToFile(saveFilePath) def saveToFile(self, fileName: str): print(fileName) self.document.write(fileName + ".docx") self.templateFile = "AppData/Templates/Letter.docx" self.document = MailMerge(self.templateFile) self.toFileName = "User Data/" convert(fileName + ".docx") os.remove(fileName + ".docx")
def write_to_word(self, number, folder, ref_wordfile): num = number document = MailMerge(ref_wordfile) document.merge(inv_date=self.date, supplier_name=self.supplier, inv_num=self.inv_num, inv_amt="$" + self.inv_amt, short_amt="$" + self.short_amt, amt_to_supplier="$" + self.amt_payable, dept_charged=self.dept, chem="$" + str(self.chem), dairy_bread="$" + str(self.dairy_bread), drinks="$" + str(self.drink), dry_goods="$" + str(self.dry_goods), freight="$" + str(self.freight), frozen_cooler="$" + str(self.frozen_cooler), meat="$" + str(self.meat), novelties="$" + str(self.novelty), paper="$" + str(self.paper), produce="$" + str(self.produce), snacks="$" + str(self.snacks), total_amt="$" + str(self.amt_payable)) print(folder) document.write(folder + f"//Invoice{num}.docx") return folder
def home(): session.pop('file_name', None) form = LandlordForm() if form.validate_on_submit(): template = "NoticeTemplate.docx" document = MailMerge(template) document.merge( LandlordName=form.lln.data, LandlordAddressLine1=form.lla.data, LandlordSuburb=form.llsu.data, LandlordState=form.llst.data, LandlordPostCode=str(form.llpc.data), ) n = str(date.today()) + str(randint(1, 10000)) bn = n.encode() m = hashlib.sha256() m.update(bn) y = m.hexdigest() file_name = "{}.docx".format(y) dir = os.getcwd() path = Path(dir + '/app/notices') os.chdir(path) document.write(file_name) session['file_name'] = file_name return redirect('/download') return render_template('home.html', title='Home', form=form)
def hardware_list_from_booking(list, bam): template = "Leihgeräte1.docx" document = MailMerge(template) myList = [] myList1 = [] counter = 0 for i in list: counter = counter + 1 if (counter == 1): switches = 1 else: switches = round(counter * 1 / 5) cable = int(counter + 2 + switches) c = str(counter) s = str(switches) x = str(cable) document.merge(Bam=bam, Laptops=c, Netzteile=c, Kabel=x, Maus=c, Switches=s, Steckdosen=s, Date=time.strftime("%d.%m.%Y")) document.write('test1.docx') os.system('start test1.docx')
def process_word(get_word_path, get_home_id): # 現在只得到香客的名稱,要其他資料 要用查資料庫 return get_word_path all_word = docx.Document() #儲存所有的檔案 all_replace_value = {} try: use_word = MailMerge(get_word_path) for i in range(len(get_home_id)): get_people_data = People_data.objects.get(name=get_home_id) all_replace_value.setdefault( str(i + 1) + "_name", str(get_people_data.name)) all_replace_value.setdefault( str(i + 1) + "_birthday", str(get_people_data.birthday.strftime('%Y年%m月%d天'))) today = date.today() all_replace_value.setdefault( str(i + 1) + "_year", str(today.year - get_people_data.birthday.year - ((today.month, today.day) < (get_people_data.birthday.month, get_people_data.birthday.day)))) use_word.merge(**all_replace_value) use_word.write("C:\\Users\\asd19\\Downloads\\OKOK.docx") os.system('C:\\Users\\asd19\\Downloads\\OKOK.docx') except Exception as e: return e return "ok" # all_replace_value
def write2docx(name, vulns_list, destFile): #得到当前main.py文件的路径,以便放 生成的模板文件 pwd = os.getcwd() #漏洞模板文件,最上面的换行不要删除 template_file = pwd + '\\vuln_template.docx' name_list = [] count = 0 #循环生成每个漏洞文件 for vuln in vulns_list: count += 1 #读取模板文件 template = MailMerge(template_file) #写入指定的字段,这里的字段和模板文件中设置的字段对应 template.merge(num=str(count), vuln_name=vuln[0], vuln_risk=vuln[1], vuln_category=name, vuln_detail=vuln[2], vuln_solution=vuln[3]) template.write(".//tmpDocx//test-{}.docx".format(count)) name_list.append(pwd + ".//tmpDocx//test-{}.docx".format(count)) #如果destfile存在则删除 if os.path.exists(destFile): os.remove(destFile) #这个速度慢,而且需要经常清理缓存,且打开的word会被关闭,没有安装office不能用 # mergeDocx_win32(destFile, name_list) #这个速度保守估计快4倍左右,一切正常 mergeDocx_pyDocx(destFile, name_list) else: # mergeDocx_win32(destFile, name_list) mergeDocx_pyDocx(destFile, name_list)
def document(): content = request.json data_entries = [] support_category_map = {} for i,j,l,n in zip(content['data'],content['hours'],content['goals'],content['hoursFrequncy']): x={} SupportCategoryName = i['SupportCategoryName'] x['SupportCategory'] = SupportCategoryName x['ItemName'] = i['SupportItemName'] x['ItemId'] = i['SupportItemNumber'] multiplication = "" if (n[-1]=="W"): x['H'] = "Hours per Week: "+ n.split(',')[0] + "\n" + "Duration: " + n.split(',')[1] + " weeks" multiplication = n.split(',')[0] + "x" + n.split(',')[1] + "x" elif (n[-1]=="M"): x['H'] = "Hours per Month: "+ n.split(',')[0] + "\n" + "Duration: " + n.split(',')[1] + " months" multiplication = n.split(',')[0] + "x" + n.split(',')[1] + "x" else: x['H'] = "Hours per plan period: "+ n + " hours" multiplication = n + "x" cost = Money(str(i['Price']*int(j)), 'USD') x['Cost'] = multiplication + Money(str(i['Price']),'USD').format('en_US') + "\n= " + cost.format('en_US') if SupportCategoryName in support_category_map: support_category_map[SupportCategoryName] += i['Price']*int(j) else: support_category_map[SupportCategoryName] = i['Price']*int(j) goals = "" for goal in l: goals = goals + goal + "\n" + "\n" x['Goals'] = goals data_entries.append(x) totalcost = "" for key,value in support_category_map.items(): totalcost = totalcost + key + " = " + Money(str(value),'USD').format('en_US') + "\n" document = MailMerge('WordTemplate.docx') total_cost = totalcost document.merge(totalcost= total_cost.format('en_US')) datetimeobject = datetime.strptime(content['start'],'%Y-%m-%d') startDate = datetimeobject.strftime('%d/%m/%Y') datetimeobject = datetime.strptime(content['end'],'%Y-%m-%d') endDate = datetimeobject.strftime('%d/%m/%Y') datetimeobject = datetime.strptime(content['today'],'%Y-%m-%d') today = datetimeobject.strftime('%d/%m/%Y') document.merge(name=str(content['name']),ndis=str(content['ndis']),sos=str(content['sos']),duration=str(int(content['duration']/7))+" weeks",start=startDate,end=endDate,today=today,policy=content['policy']) document.merge_rows('SupportCategory',data_entries) document.write('test-output.docx') return send_file('test-output.docx', as_attachment=True)
def save_doc(self, file_name, **kwargs): document = MailMerge(TEMPLATE) document.merge(**kwargs) path = asksaveasfile(mode="w", defaultextension=".doc", initialfile=file_name) if path: path = path.name document.write(path)
def deficiency_letter(petitioner, petAddress, petCityStateZip, mhp, lots, sigsNeeded, uniques, duplicates, reqs): scriptDir = os.path.dirname("mediation.py") count = 0 for deficiency in reqs: if deficiency is True: count += 1 name = HumanName(petitioner) titleLast = name.title + " " + name.last sigsShort = sigsNeeded - uniques r2, r3, r4, r5 = "", "", "", "" # equivalent to reqs[0] through reqs[3] if reqs[0] is False: relPath = "letter_templates/Requirement2Template.txt" r2FilePath = os.path.join(scriptDir, relPath) data = open(r2FilePath) r2 = data.read() r2 = "\n\n" + r2 % (str(lots), str(sigsNeeded), str(uniques), str(duplicates), str(sigsShort)) data.close() if reqs[1] is False: relPath = "letter_templates/Requirement3Template.txt" r3FilePath = os.path.join(scriptDir, relPath) data = open(r3FilePath) r3 = "\n\n" + data.read() data.close() if reqs[2] is False: relPath = "letter_templates/Requirement4Template.txt" r4FilePath = os.path.join(scriptDir, relPath) data = open(r4FilePath) r4 = "\n\n" + data.read() data.close() if reqs[3] is False: relPath = "letter_templates/Requirement5Template.txt" r5FilePath = os.path.join(scriptDir, relPath) data = open(r5FilePath) r5 = "\n\n" + data.read() data.close() singleOrPlural = "deficiency" if count == 1 else "deficiencies" relPath = "letter_templates/DeficiencyLetterTemplate.docx" deficientFilePath = os.path.join(scriptDir, relPath) document = MailMerge(deficientFilePath) document.merge(petitioner=petitioner, petAddress=petAddress, petCityStateZip=petCityStateZip, mhp=mhp, titleLast=titleLast, singleOrPlural=singleOrPlural, r2=r2, r3=r3, r4=r4, r5=r5) docName = mhp.replace(" ", "") + "DeficiencyLetter.docx" relPath = "output_files/" + docName outputFilePath = os.path.join(scriptDir, relPath) document.write(outputFilePath) create_pdf(outputFilePath) print "\nA deficiency letter has been created!\n"
def write2docx(name, vulns_list, destFile): #得到当前main.py文件的路径,以便放 生成的模板文件 pwd = os.getcwd() #漏洞模板文件,最上面的换行不要删除 template_file = pwd + '\\vuln_template.docx' name_list = [] count = 0 #循环生成每个漏洞文件 for vuln in vulns_list: count += 1 #读取模板文件 template = MailMerge(template_file) #写入指定的字段,这里的字段和模板文件中设置的字段对应 template.merge(num=str(count), vuln_name=vuln[0], vuln_risk=vuln[1], vuln_category=name, vuln_detail=vuln[2], vuln_solution=vuln[3]) template.write("tmpDocx\\test-{}.docx".format(count)) name_list.append(pwd + "\\tmpDocx\\test-{}.docx".format(count)) # print('写入时的文件名:'+destFile) #如果destfile存在则删除 if os.path.exists(destFile): os.remove(destFile) #这个速度慢,而且需要经常清理缓存,且打开的word会被关闭,没有安装office不能用 # mergeDocx_win32(destFile, name_list) #这个速度保守估计快4倍左右,一切正常 if len(name_list) > 0: mergeDocx_pyDocx(destFile, name_list) #提示信息 result_text.insert('end', "写入word成功,请到原漏洞文件目录下查看。 \n") result_text.update() else: print("该文件无风险漏洞!") result_text.insert('end', "该文件无风险漏洞。 \n") result_text.update() else: # mergeDocx_win32(destFile, name_list) if len(name_list) > 0: mergeDocx_pyDocx(destFile, name_list) #提示信息 result_text.insert('end', "写入word成功,请到原漏洞文件目录下查看。 \n") result_text.update() else: print("该文件无风险漏洞!") result_text.insert('end', "该文件无风险漏洞。 \n") result_text.update() #如果生成文件,则打开并替换空行 if os.path.exists(destFile): replaceSpace(destFile)
def makeApplications(): template = "mainFolder/application_template.docx" search_url = "https://no.jooble.org/jobb-ekstrahjelper%2Fbutikkselger-deltid/Stavanger?p=" # plus pagenumber target_string = "ckey=ekstrahjelper%2fbutikkselger+deltid" numOfLinks = 0 numOfPagesSearched = int( input("Number of pages you want searched (max 41 atm): ")) nameStr = input('Full name: ') numStr = input('Phone number: ') emailStr = input('E-mail: ') linkRecurrence = {} start_time = time.time() for i in range(numOfPagesSearched): links = [] html_page = urllib.request.urlopen(search_url + str(i)) soup_main = BeautifulSoup(html_page, features="lxml") for link in soup_main.findAll('a', attrs={'href': re.compile("^https://")}): if target_string in link.get('href'): numOfLinks += 1 links.append(link.get('href')) for link in links: valueList = [] html_page = urllib.request.urlopen(link) soup_page = BeautifulSoup(html_page, features="lxml") values = soup_page.findAll(attrs={'class': 'value-column'}) for value in values: valueList.append(value.text.strip()) company = valueList[0] if company == "Stavanger" or company == "Sandnes" or "/" in company or "|" in company: continue if company not in linkRecurrence: linkRecurrence[company] = 0 name = company else: linkRecurrence[company] = linkRecurrence.get(company) + 1 name = f"{company}_{linkRecurrence.get(company)}" print(f"Handling: {company}") location = valueList[1] document = MailMerge(template) document.merge(date='{:%d-%b-%Y}'.format(date.today()), company=company, link=link, name=nameStr, email=emailStr, number=numStr) document.write(f"mainFolder/applications/{name}.docx") print( f"Number of links handled: {numOfLinks}, time elapsed: {int(time.time()-start_time)}s" ) print( f"Efficiency: {numOfLinks/int(time.time()-start_time)} applications per second" )
def fillContract(fileName, cid): base = db.dbSql() sql = ''' SELECT c.cdate "DATA", c.cid "NUM_CONTRACT", c.enddate "END_DATA", o.sid osid, o.sname "CON.NAME", o.sfullname "CON.FULL_NAME", o.inn "CON.INN", o.stype "CON.TYPE", o.regnum "CON.REG_NUMBER" , o.regdate "CON.REG_DATE", o.taxation "CON.TAXATION", o.admin "CON.ADMIN", o.contacts "CON.CONTACTS", u.sid usid, u.sname "CUS.NAME", u.sfullname "CUS.FULL_NAME", u.inn "CUS.INN", u.stype "CUS.TYPE", u.regnum "CUS.REG_NUMBER", u.regdate "CUS.REG_DATE", u.taxation "CUS.TAXATION", u.admin "CUS.ADMIN", u.contacts "CUS.CONTACTS", b.sum "SUM" FROM contracts c LEFT OUTER JOIN subjects o ON c.contractor = o.sid LEFT OUTER JOIN subjects u ON c.customer = u.sid LEFT OUTER JOIN budgetrules b ON c.budget = b.brid WHERE cid = {0}; ''' rows = base.request(sql.format(int(cid))) vars = rows[0] if len(rows) > 0 else {} sql2 = ''' SELECT s.sid, GROUP_CONCAT(a.iban SEPARATOR ', ' ) iban FROM subjects s INNER JOIN accounts a ON a.sid = s.sid WHERE a.iban <> '' AND s.sid = {0} GROUP BY s.sid ''' sids = {'osid': 'CON.IBAN', 'usid': 'CUS.IBAN'} for sidEl in sids: if sidEl in vars: rows = base.request(sql2.format(vars.get('osid'))) vars[sids[sidEl]] = rows[0]['iban'] if len(rows) > 0 else '' for el in vars: vars[el] = str(vars[el]) # print('complete 61', vars) doc = MailMerge(fileName) doc.merge(**vars) doc.write(fileName + 'new') return fileName + 'new'
def write_final_options(self, name): template = "test-print.docx" document = MailMerge(template) document.merge_rows('item', docx_dict) document.merge(**merge2) if name.endswith('.docx'): document.write(name) else: document.write(name + '.docx') document.close()
def get(self, request, *args, **kwargs): username = request.session.get("username") try: user = Commentuser.objects.get(username=username) ins_nm = user.ins.ins_nm acceptcheck = AcceptCheck.objects.get(ins_nm=ins_nm) softinfo = SoftInfo.objects.get(acceptcheck=acceptcheck) except Exception as e: return json_response({"msg": str(e)}) # 打印模板 path = "media/upload/apply_temp/技术验收软件信息表01.docx" # 创建邮件合并文档并查看所有字段 document_1 = MailMerge(path) document_1.merge( ins_nm=ins_nm, company_adr=acceptcheck.company_adr, computer_adr=acceptcheck.computer_adr, zip_code=acceptcheck.zip_code, fax=acceptcheck.fax, contacts=acceptcheck.contacts, phone=acceptcheck.phone, email=acceptcheck.email, reply=acceptcheck.reply, soft_nm=softinfo.soft_nm, soft_ty=softinfo.soft_ty, database=softinfo.database, operat_sys=softinfo.operat_sys, cd_num=softinfo.cd_num, instruct_num=softinfo.instruct_num, enclosure_num=softinfo.enclosure_num, acces_sys=softinfo.acces_sys, acce_ty=acceptcheck.acce_ty, pro_line_num=softinfo.pro_line_num, pro_acc_num=softinfo.pro_acc_num, test_line_num=softinfo.test_line_num, test_acc_num=softinfo.test_acc_num, front_info=softinfo.front_info, MBFE=softinfo.MBFE, apply_mid=softinfo.apply_mid, message_mid=softinfo.message_mid, ) target = 'media/upload/tec_accept/' raw_name = ins_nm + ".docx" if not os.path.exists(os.path.dirname(target)): os.makedirs(target) file_path = os.path.join(target, raw_name) document_1.write(file_path) file = open(file_path, 'rb') response = FileResponse(file) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename=' + raw_name return response
def process_with_mail_merge(input_file, _filled_dict, user_defined_name): original_path = input_file #print('funkcia: {}'.format(BASE_DIR + input_file)) input_file = BASE_DIR + input_file document = MailMerge(input_file) _out_name = original_path.strip( '.docx') + user_defined_name + '.docx' document.merge(**_filled_dict) document.write(BASE_DIR + _out_name) return _out_name
def generate_file(template): for i in range(ncols): # 循环逐行打印 if i == 1: # 选择第2列,即B列 document = MailMerge(template) document.merge( float_to_str(table.col_values(0)[2])=float_to_str( table.col_values(i)[2]) # 手填 ) wordname = float_to_str(table.col_values(i)[2]) + float_to_str( table.col_values(i)[3]) + float_to_str( table.col_values(i)[4]) + "分包" + '合同.docx' # 甲方作为文件名 document.write(wordname) # 创建新文件
def create_document(cfg, output="output.docx", cfg_date=False): template_docx = TEMPLATE_1 if cfg_date: template_docx = TEMPLATE_2 document = MailMerge(template_docx) # print(document.get_merge_fields()) section_user = cfg["user"] section_bank = cfg["bank"] section_target = cfg["target"] section_service = cfg["service"] section_custom_date = cfg["custom_date"] if cfg_date: document.merge( amount=section_service["amount"], bankName=section_bank["bankName"], bankNum=str(section_bank["bankNum"]), business=section_target["business"], name=section_user["name"], nameUpper=section_user["name"].upper(), nit=section_target["nit"], nid=str(section_user["nid"]), nidCity=section_user["nidCity"], day=str(section_custom_date["day"]), dayStart=str(section_custom_date["dayStart"]), dayEnd=str(section_custom_date["dayEnd"]), month=section_custom_date["month"], monthStart=section_custom_date["monthStart"], monthEnd=section_custom_date["monthEnd"], year=str(section_custom_date["year"]), yearStart=str(section_custom_date["yearStart"]), yearEnd=str(section_custom_date["yearEnd"]), ) else: formated_date, formated_date_start, formated_date_end = get_date() document.merge( amount=section_service["amount"], bankName=section_bank["bankName"], bankNum=str(section_bank["bankNum"]), business=section_target["business"], name=section_user["name"], nameUpper=section_user["name"].upper(), nit=section_target["nit"], nid=str(section_user["nid"]), nidCity=section_user["nidCity"], currentDate=formated_date, dateStart=formated_date_start, dateEnd=formated_date_end, ) document.write(output) document.close()
class MergeTableRowsMultipartTest(EtreeMixin, unittest.TestCase): def setUp(self): self.document = MailMerge(path.join(path.dirname(__file__), 'test_merge_table_multipart.docx')) self.expected_xml = '<w:document xmlns:ns1="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p w:rsidP="00DA4DE0" w:rsidR="00231DA5" w:rsidRDefault="00DA4DE0"><w:pPr><w:pStyle w:val="Ttulo" /></w:pPr><w:r><w:t>Grades</w:t></w:r></w:p><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:r><w:t>Bouke Haarsma</w:t></w:r><w:r w:rsidR="002C29C5"><w:t xml:space="preserve"> </w:t></w:r><w:r w:rsidR="00DA4DE0"><w:t>received the grades</w:t></w:r><w:r w:rsidR="002C29C5"><w:t xml:space="preserve"> for </w:t></w:r><w:r><w:t /></w:r><w:r w:rsidR="00DA4DE0"><w:t xml:space="preserve"> in the table below.</w:t></w:r></w:p><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0" /><w:tbl><w:tblPr><w:tblStyle w:val="Sombreadoclaro-nfasis1" /><w:tblW w:type="auto" w:w="0" /><w:tblLook w:val="04E0" /></w:tblPr><w:tblGrid><w:gridCol w:w="1777" /><w:gridCol w:w="4894" /><w:gridCol w:w="1845" /></w:tblGrid><w:tr w:rsidR="00DA4DE0" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:val="100000000000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0"><w:r><w:t>Class Code</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0"><w:pPr><w:cnfStyle w:val="100000000000" /></w:pPr><w:r><w:t>Class Name</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0"><w:pPr><w:cnfStyle w:val="100000000000" /></w:pPr><w:r><w:t>Grade</w:t></w:r></w:p></w:tc></w:tr><w:tr w:rsidR="00DA4DE0" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:val="000000100000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:r><w:t>ECON101</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:pPr><w:cnfStyle w:val="000000100000" /></w:pPr><w:r><w:t>Economics 101</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:pPr><w:cnfStyle w:val="000000100000" /></w:pPr><w:r><w:t>A</w:t></w:r></w:p></w:tc></w:tr><w:tr w:rsidR="00DA4DE0" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:val="000000100000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:r><w:t>ECONADV</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:pPr><w:cnfStyle w:val="000000100000" /></w:pPr><w:r><w:t>Economics Advanced</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:pPr><w:cnfStyle w:val="000000100000" /></w:pPr><w:r><w:t>B</w:t></w:r></w:p></w:tc></w:tr><w:tr w:rsidR="00DA4DE0" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:val="000000100000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:r><w:t>OPRES</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:pPr><w:cnfStyle w:val="000000100000" /></w:pPr><w:r><w:t>Operations Research</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="0037127B"><w:pPr><w:cnfStyle w:val="000000100000" /></w:pPr><w:r><w:t>A</w:t></w:r></w:p></w:tc></w:tr><w:tr w:rsidR="00C829DD" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:val="010000000000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00C829DD" w:rsidRDefault="00C829DD"><w:r><w:t>THESIS</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00C829DD" w:rsidRDefault="00C829DD"><w:pPr><w:cnfStyle w:val="010000000000" /></w:pPr><w:r><w:t>Final thesis</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p w:rsidP="00DA4DE0" w:rsidR="00C829DD" w:rsidRDefault="0037127B"><w:pPr><w:cnfStyle w:val="010000000000" /></w:pPr><w:r><w:t>A</w:t></w:r></w:p></w:tc></w:tr></w:tbl><w:p w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0" w:rsidRPr="00DA4DE0"><w:bookmarkStart w:id="0" w:name="_GoBack" /><w:bookmarkEnd w:id="0" /></w:p><w:sectPr w:rsidR="00DA4DE0" w:rsidRPr="00DA4DE0" w:rsidSect="003B4151"><w:headerReference ns1:id="rId7" w:type="default" /><w:pgSz w:h="16840" w:w="11900" /><w:pgMar w:bottom="1440" w:footer="708" w:gutter="0" w:header="708" w:left="1800" w:right="1800" w:top="1672" /><w:cols w:space="708" /><w:docGrid w:linePitch="360" /></w:sectPr></w:body></w:document>' self.expected_tree = etree.fromstring(self.expected_xml) def test_merge_rows_on_multipart_file(self): self.assertEqual(self.document.get_merge_fields(), {'student_name', 'study_name', 'class_name', 'class_code', 'class_grade', 'thesis_grade'}) self.document.merge( student_name='Bouke Haarsma', study='Industrial Engineering and Management', thesis_grade='A', ) self.document.merge_rows('class_code', [ {'class_code': 'ECON101', 'class_name': 'Economics 101', 'class_grade': 'A'}, {'class_code': 'ECONADV', 'class_name': 'Economics Advanced', 'class_grade': 'B'}, {'class_code': 'OPRES', 'class_name': 'Operations Research', 'class_grade': 'A'}, ]) with tempfile.TemporaryFile() as outfile: self.document.write(outfile) for part in self.document.parts.values(): # only check the document part if (part.getroot().tag == '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}document'): self.assert_equal_tree(self.expected_tree, part.getroot()) def test_merge_unified_on_multipart_file(self): self.document.merge( student_name='Bouke Haarsma', study='Industrial Engineering and Management', thesis_grade='A', class_code=[ {'class_code': 'ECON101', 'class_name': 'Economics 101', 'class_grade': 'A'}, {'class_code': 'ECONADV', 'class_name': 'Economics Advanced', 'class_grade': 'B'}, {'class_code': 'OPRES', 'class_name': 'Operations Research', 'class_grade': 'A'}, ] ) with tempfile.TemporaryFile() as outfile: self.document.write(outfile) for part in self.document.parts.values(): # only check the document part if (part.getroot().tag == '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}document'): self.assert_equal_tree(self.expected_tree, part.getroot()) def tearDown(self): self.document.close()
def test(self): document = MailMerge('tests/test_macword2011.docx') self.assertEquals(document.get_merge_fields(), set(['first_name', 'last_name', 'country', 'state', 'postal_code', 'date', 'address_line', 'city'])) document.merge(first_name='Bouke', last_name='Haarsma', country='The Netherlands', state=None, postal_code='9723 ZA', city='Groningen', address_line='Helperpark 278d', date='May 22nd, 2013') with tempfile.NamedTemporaryFile() as outfile: document.write(outfile)
def test(self): document = MailMerge('tests/test_winword2010.docx') self.assertEquals(document.get_merge_fields(), set(['Titel', 'Voornaam', 'Achternaam', 'Adresregel_1', 'Postcode', 'Plaats', 'Provincie', 'Land_of_regio'])) document.merge(Voornaam='Bouke', Achternaam='Haarsma', Land_of_regio='The Netherlands', Provincie=None, Postcode='9723 ZA', Plaats='Groningen', Adresregel_1='Helperpark 278d', Titel='dhr.') with tempfile.NamedTemporaryFile() as outfile: document.write(outfile.name)
def test(self): document = MailMerge(path.join(path.dirname(__file__), 'test_macword2011.docx')) self.assertEqual(document.get_merge_fields(), set(['first_name', 'last_name', 'country', 'state', 'postal_code', 'date', 'address_line', 'city'])) document.merge(first_name='Bouke', last_name='Haarsma', country='The Netherlands', state=None, postal_code='9723 ZA', city='Groningen', address_line='Helperpark 278d', date='May 22nd, 2013') with tempfile.TemporaryFile() as outfile: document.write(outfile) expected_tree = etree.fromstring( '<w:document xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" ' 'xmlns:ns1="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w="http://schemas' '.openxmlformats.org/wordprocessingml/2006/main" mc:Ignorable="w14 wp14">' '<w:body><w:p ns1:paraId="25CDEC86" ns1:textId="77777777" ' 'w:rsidR="00FB567A" w:rsidRDefault="00541684"><w:r><w:t>Bouke</w:t></w:r><w:r w:rsidR="00916690"><w:t ' 'xml:space="preserve"> </w:t></w:r><w:r><w:t>Haarsma</w:t></w:r></w:p><w:p ns1:paraId="67F7A559" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00541684"><w:r><w:t>Helperpark ' '278d</w:t></w:r></w:p><w:p ns1:paraId="228F2AEA" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00541684"><w:r><w:t>9723 ZA</w:t></w:r><w:r><w:t xml:space="preserve"> ' '</w:t></w:r><w:r><w:t>Groningen</w:t></w:r><w:bookmarkStart w:id="0" w:name="_GoBack" /><w:bookmarkEnd ' 'w:id="0" /><w:r w:rsidR="00916690"><w:t xml:space="preserve"> </w:t></w:r><w:r><w:t /></w:r><w:r ' 'w:rsidR="00916690"><w:t xml:space="preserve"> </w:t></w:r><w:r><w:t>The ' 'Netherlands</w:t></w:r></w:p><w:p ns1:paraId="696E15D7" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690" /><w:p ns1:paraId="3F48DA35" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690" /><w:p ns1:paraId="68E7FBD1" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690"><w:r><w:t xml:space="preserve">Groningen, </w:t></w:r><w:r><w:t>May 22nd, ' '2013</w:t></w:r><w:r><w:t>,</w:t></w:r></w:p><w:p ns1:paraId="26B47597" ns1:textId="77777777" ' 'w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="740FF493" ns1:textId="77777777" ' 'w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="232699A0" ns1:textId="77777777" ' 'w:rsidR="00916690" w:rsidRDefault="00916690"><w:r><w:t xml:space="preserve">Dear ' '</w:t></w:r><w:r><w:t>Bouke</w:t></w:r><w:r><w:t>,</w:t></w:r></w:p><w:p ns1:paraId="1AE04A19" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="298752B0" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="477BE6DB" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690"><w:r><w:t>I hope this message finds ' 'you well.</w:t></w:r></w:p><w:p ns1:paraId="77542CE2" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690" /><w:p ns1:paraId="734AC552" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690" /><w:p ns1:paraId="1680D84C" ns1:textId="77777777" w:rsidR="00916690" ' 'w:rsidRDefault="00916690"><w:r><w:t>Kind regards,</w:t></w:r></w:p><w:p ns1:paraId="67F698AC" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690" /><w:p ns1:paraId="7A4C001B" ' 'ns1:textId="77777777" w:rsidR="00916690" w:rsidRDefault="00916690"><w:r><w:t>docx-mailmerge' '.</w:t></w:r></w:p><w:sectPr w:rsidR="00916690" w:rsidSect="00CA5A66"><w:pgSz w:h="16840" w:w="11900" ' '/><w:pgMar w:bottom="1417" w:footer="708" w:gutter="0" w:header="708" w:left="1417" w:right="1417" ' 'w:top="1417" /><w:cols w:space="708" /><w:docGrid w:linePitch="360" /></w:sectPr></w:body></w:document>') self.assert_equal_tree(expected_tree, list(document.parts.values())[0].getroot())
def apply_mailmerge(self, context, filename="example.docx"): # Return a django request response with a docx download. docx = StringIO() mailmerge = MailMerge(self.get_full_path()) mailmerge.merge(context) mailmerge.write(docx) mailmerge.close() # return response docx.seek(0) response = HttpResponse(docx) response['Content-Disposition'] = 'attachment; filename={}'.format(filename) response['Content-Type'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' return response
class MergeTableRowsTest(EtreeMixin, unittest.TestCase): def setUp(self): self.document = MailMerge(path.join(path.dirname(__file__), 'test_merge_table_rows.docx')) self.expected_tree = ElementTree.fromstring('<w:document xmlns:ns1="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p ns1:paraId="28ACC80D" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00231DA5" w:rsidRDefault="00DA4DE0"><w:pPr><w:pStyle w:val="Title" /></w:pPr><w:proofErr w:type="spellStart" /><w:r><w:t>Grades</w:t></w:r><w:proofErr w:type="spellEnd" /></w:p><w:p ns1:paraId="07836F52" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:r><w:t>Bouke Haarsma</w:t></w:r><w:r w:rsidR="002C29C5"><w:t xml:space="preserve"> </w:t></w:r><w:proofErr w:type="spellStart" /><w:r w:rsidR="00DA4DE0"><w:t>received</w:t></w:r><w:proofErr w:type="spellEnd" /><w:r w:rsidR="00DA4DE0"><w:t xml:space="preserve"> the </w:t></w:r><w:proofErr w:type="spellStart" /><w:r w:rsidR="00DA4DE0"><w:t>grades</w:t></w:r><w:proofErr w:type="spellEnd" /><w:r w:rsidR="002C29C5"><w:t xml:space="preserve"> </w:t></w:r><w:proofErr w:type="spellStart" /><w:r w:rsidR="002C29C5"><w:t>for</w:t></w:r><w:proofErr w:type="spellEnd" /><w:r w:rsidR="002C29C5"><w:t xml:space="preserve"> </w:t></w:r><w:r><w:t /></w:r><w:r w:rsidR="00DA4DE0"><w:t xml:space="preserve"> in the </w:t></w:r><w:proofErr w:type="spellStart" /><w:r w:rsidR="00DA4DE0"><w:t>table</w:t></w:r><w:proofErr w:type="spellEnd" /><w:r w:rsidR="00DA4DE0"><w:t xml:space="preserve"> below.</w:t></w:r></w:p><w:p ns1:paraId="58525309" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0" /><w:tbl><w:tblPr><w:tblStyle w:val="LightShading-Accent1" /><w:tblW w:type="auto" w:w="0" /><w:tblLook w:firstColumn="1" w:firstRow="1" w:lastColumn="0" w:lastRow="1" w:noHBand="0" w:noVBand="1" w:val="04E0" /></w:tblPr><w:tblGrid><w:gridCol w:w="1777" /><w:gridCol w:w="4894" /><w:gridCol w:w="1845" /></w:tblGrid><w:tr ns1:paraId="599252DD" ns1:textId="77777777" w:rsidR="00DA4DE0" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="1" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="100000000000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="1" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p ns1:paraId="69486D96" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0"><w:r><w:t>Class Code</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p ns1:paraId="1AA11439" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="1" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="100000000000" /></w:pPr><w:r><w:t>Class Name</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p ns1:paraId="3091846F" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="1" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="100000000000" /></w:pPr><w:r><w:t>Grade</w:t></w:r></w:p></w:tc></w:tr><w:tr ns1:paraId="1699D5B6" ns1:textId="77777777" w:rsidR="00DA4DE0" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="1" w:oddVBand="0" w:val="000000100000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="1" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p ns1:paraId="5D81DF7F" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:r><w:t>ECON101</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p ns1:paraId="5A67E49A" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="1" w:oddVBand="0" w:val="000000100000" /></w:pPr><w:r><w:t>Economics 101</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p ns1:paraId="5EB9BD23" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="1" w:oddVBand="0" w:val="000000100000" /></w:pPr><w:r><w:t>A</w:t></w:r></w:p></w:tc></w:tr><w:tr ns1:paraId="1699D5B6" ns1:textId="77777777" w:rsidR="00DA4DE0" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="1" w:oddVBand="0" w:val="000000100000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="1" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p ns1:paraId="5D81DF7F" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:r><w:t>ECONADV</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p ns1:paraId="5A67E49A" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="1" w:oddVBand="0" w:val="000000100000" /></w:pPr><w:r><w:t>Economics Advanced</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p ns1:paraId="5EB9BD23" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="1" w:oddVBand="0" w:val="000000100000" /></w:pPr><w:r><w:t>B</w:t></w:r></w:p></w:tc></w:tr><w:tr ns1:paraId="1699D5B6" ns1:textId="77777777" w:rsidR="00DA4DE0" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="1" w:oddVBand="0" w:val="000000100000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="1" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p ns1:paraId="5D81DF7F" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:r><w:t>OPRES</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p ns1:paraId="5A67E49A" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="1" w:oddVBand="0" w:val="000000100000" /></w:pPr><w:r><w:t>Operations Research</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p ns1:paraId="5EB9BD23" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00C829DD"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="1" w:oddVBand="0" w:val="000000100000" /></w:pPr><w:r><w:t>A</w:t></w:r></w:p></w:tc></w:tr><w:tr ns1:paraId="0B5730FD" ns1:textId="77777777" w:rsidR="00C829DD" w:rsidTr="00C829DD"><w:trPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="1" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="010000000000" /></w:trPr><w:tc><w:tcPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="1" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="0" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="001000000000" /><w:tcW w:type="dxa" w:w="1809" /></w:tcPr><w:p ns1:paraId="6A211A5A" ns1:textId="4E90EB38" w:rsidP="00DA4DE0" w:rsidR="00C829DD" w:rsidRDefault="00C829DD"><w:r><w:t>THESIS</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="5529" /></w:tcPr><w:p ns1:paraId="12FCE443" ns1:textId="289CA6C6" w:rsidP="00DA4DE0" w:rsidR="00C829DD" w:rsidRDefault="00C829DD"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="1" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="010000000000" /></w:pPr><w:proofErr w:type="spellStart" /><w:r><w:t>Final</w:t></w:r><w:proofErr w:type="spellEnd" /><w:r><w:t xml:space="preserve"> thesis</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="1178" /></w:tcPr><w:p ns1:paraId="0ACD9198" ns1:textId="413A3A4D" w:rsidP="00DA4DE0" w:rsidR="00C829DD" w:rsidRDefault="00C829DD"><w:pPr><w:cnfStyle w:evenHBand="0" w:evenVBand="0" w:firstColumn="0" w:firstRow="0" w:firstRowFirstColumn="0" w:firstRowLastColumn="0" w:lastColumn="0" w:lastRow="1" w:lastRowFirstColumn="0" w:lastRowLastColumn="0" w:oddHBand="0" w:oddVBand="0" w:val="010000000000" /></w:pPr><w:r><w:t>A</w:t></w:r></w:p></w:tc></w:tr></w:tbl><w:p ns1:paraId="26A87379" ns1:textId="77777777" w:rsidP="00DA4DE0" w:rsidR="00DA4DE0" w:rsidRDefault="00DA4DE0" w:rsidRPr="00DA4DE0"><w:bookmarkStart w:id="0" w:name="_GoBack" /><w:bookmarkEnd w:id="0" /></w:p><w:sectPr w:rsidR="00DA4DE0" w:rsidRPr="00DA4DE0" w:rsidSect="002C0659"><w:pgSz w:h="16840" w:w="11900" /><w:pgMar w:bottom="1440" w:footer="708" w:gutter="0" w:header="708" w:left="1800" w:right="1800" w:top="1440" /><w:cols w:space="708" /><w:docGrid w:linePitch="360" /></w:sectPr></w:body></w:document>') # noqa def test_merge_rows(self): self.assertEqual(self.document.get_merge_fields(), {'student_name', 'study_name', 'class_name', 'class_code', 'class_grade', 'thesis_grade'}) self.document.merge( student_name='Bouke Haarsma', study='Industrial Engineering and Management', thesis_grade='A', ) self.document.merge_rows('class_code', [ {'class_code': 'ECON101', 'class_name': 'Economics 101', 'class_grade': 'A'}, {'class_code': 'ECONADV', 'class_name': 'Economics Advanced', 'class_grade': 'B'}, {'class_code': 'OPRES', 'class_name': 'Operations Research', 'class_grade': 'A'}, ]) with tempfile.TemporaryFile() as outfile: self.document.write(outfile) self.assert_equal_tree(self.expected_tree, list(self.document.parts.values())[0].getroot()) def test_merge_unified(self): self.document.merge( student_name='Bouke Haarsma', study='Industrial Engineering and Management', thesis_grade='A', class_code=[ {'class_code': 'ECON101', 'class_name': 'Economics 101', 'class_grade': 'A'}, {'class_code': 'ECONADV', 'class_name': 'Economics Advanced', 'class_grade': 'B'}, {'class_code': 'OPRES', 'class_name': 'Operations Research', 'class_grade': 'A'}, ] ) with tempfile.TemporaryFile() as outfile: self.document.write(outfile) self.assert_equal_tree(self.expected_tree, list(self.document.parts.values())[0].getroot())
def test(self): document = MailMerge(path.join(path.dirname(__file__), 'test_winword2010.docx')) self.assertEqual(document.get_merge_fields(), set(['Titel', 'Voornaam', 'Achternaam', 'Adresregel_1', 'Postcode', 'Plaats', 'Provincie', 'Land_of_regio'])) document.merge(Voornaam='Bouke', Achternaam='Haarsma', Land_of_regio='The Netherlands', Provincie=None, Postcode='9723 ZA', Plaats='Groningen', Adresregel_1='Helperpark 278d', Titel='dhr.') with tempfile.NamedTemporaryFile() as outfile: document.write(outfile) expected_tree = ElementTree.fromstring( '<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p ' 'w:rsidR="00886208" w:rsidRDefault="00886208"><w:r><w:t>dhr.</w:t></w:r><w:r ' 'w:rsidRPr="00886208"><w:rPr><w:lang w:val="nl-NL" /></w:rPr><w:t xml:space="preserve"> ' '</w:t></w:r><w:r><w:t>Bouke</w:t></w:r><w:r w:rsidRPr="00886208"><w:rPr><w:lang w:val="nl-NL" ' '/></w:rPr><w:t xml:space="preserve"> </w:t></w:r><w:r><w:t>Haarsma</w:t></w:r></w:p><w:p ' 'w:rsidR="00886208" w:rsidRDefault="00886208" w:rsidRPr="00886208"><w:pPr><w:rPr><w:lang w:val="nl-NL" ' '/></w:rPr></w:pPr><w:r><w:t>Helperpark 278d</w:t></w:r></w:p><w:p w:rsidR="00886208" ' 'w:rsidRDefault="00886208"><w:r><w:t>9723 ZA</w:t></w:r><w:r w:rsidRPr="00886208"><w:rPr><w:lang ' 'w:val="nl-NL" /></w:rPr><w:t xml:space="preserve"> </w:t></w:r><w:r><w:t>Groningen</w:t></w:r><w:r ' 'w:rsidRPr="00886208"><w:rPr><w:lang w:val="nl-NL" /></w:rPr><w:t xml:space="preserve"> ' '</w:t></w:r><w:r><w:t /></w:r><w:r w:rsidRPr="00886208"><w:rPr><w:lang w:val="nl-NL" /></w:rPr><w:t ' 'xml:space="preserve"> </w:t></w:r><w:r><w:t>The Netherlands</w:t></w:r></w:p><w:p w:rsidR="00886208" ' 'w:rsidRDefault="00886208" /><w:p w:rsidR="00886208" w:rsidRDefault="00886208"><w:r><w:t>Groningen,' '</w:t></w:r></w:p><w:p w:rsidR="00886208" w:rsidRDefault="00886208"><w:bookmarkStart w:id="0" ' 'w:name="_GoBack" /><w:bookmarkEnd w:id="0" /></w:p><w:p w:rsidR="004D7161" ' 'w:rsidRDefault="00886208"><w:r><w:t xml:space="preserve">Dear ' '</w:t></w:r><w:r><w:t>Bouke</w:t></w:r><w:r><w:t>,</w:t></w:r></w:p><w:p w:rsidR="00886208" ' 'w:rsidRDefault="00886208" /><w:p w:rsidR="00886208" w:rsidRDefault="00886208"><w:r><w:t>I hope this ' 'document from WinWord 2010 finds you well.</w:t></w:r></w:p><w:p w:rsidR="00886208" ' 'w:rsidRDefault="00886208" /><w:p w:rsidR="00886208" w:rsidRDefault="00886208"><w:r><w:t>Kind regards,' '</w:t></w:r></w:p><w:p w:rsidR="00886208" w:rsidRDefault="00886208" ' 'w:rsidRPr="00886208"><w:pPr><w:rPr><w:lang w:val="en-US" /></w:rPr></w:pPr><w:proofErr ' 'w:type="spellStart" /><w:r><w:t>docx-mailmerge</w:t></w:r><w:proofErr w:type="spellEnd" /><w:r><w:t>' '.</w:t></w:r></w:p><w:sectPr w:rsidR="00886208" w:rsidRPr="00886208"><w:pgSz w:h="16838" w:w="11906" ' '/><w:pgMar w:bottom="1417" w:footer="708" w:gutter="0" w:header="708" w:left="1417" w:right="1417" ' 'w:top="1417" /><w:cols w:space="708" /><w:docGrid w:linePitch="360" /></w:sectPr></w:body></w:document>') self.assert_equal_tree(expected_tree, list(document.parts.values())[0].getroot())