Example #1
0
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")
Example #2
0
    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)
Example #3
0
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))
Example #5
0
    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"
Example #7
0
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)
Example #8
0
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()
Example #10
0
    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())
Example #12
0
    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.")
Example #13
0
    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('消息', '模板文件生成成功')
Example #16
0
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")
Example #17
0
 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
Example #18
0
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)
Example #19
0
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')
Example #20
0
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
Example #21
0
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)
Example #22
0
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"
Example #25
0
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)
Example #26
0
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"
    )
Example #27
0
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'
Example #28
0
 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()
Example #29
0
    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
Example #30
0
 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
Example #31
0
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)  # 创建新文件
Example #32
0
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())
Example #37
0
    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())