python - 使用 docx 模块使用 Python 检查 .docx 形式的复选框

标签 python python-2.7 arcgis python-docx

我正在尝试使用 Python 2.7 的 docx 模块填写 word 文档表单。我可以很好地修改文本元素,但我很难弄清楚如何选中是或否复选框。

我如何着手检查表单中的一个复选框。我尝试了几种不同的方法,但我认为这一切都对我不利,因为我不知道在涉及复选框时 docx xml 的结构。

我能否使用 Bookmark 属性找到特定的复选框并如下图所示选中它?

enter image description here

我已将测试表格的副本上传到 Google Drive here .

最佳答案

好吧,在经历了很多挫折之后,我终于想出了如何选中一个复选框。 checkbox 元素中有一个元素表示该框是否被选中。我基本上能够使用以下函数创建该元素。

from docx.oxml import OxmlElement
from docx.oxml.ns import qn

def checkedElement():
    elm = OxmlElement('w:checked')
    elm.set(qn('w:val'),"true")
    return elm

我可以使用以下函数在表格单元格中找到所有复选框。由于"is"始终是每个单元格中的第一个复选框,我可以将"is"检查的索引设置为 0,将“否”检查设置为索引 1,然后我可以将选中的元素附加到复选框元素中:

def yesNoCheck(yes_no,tableIdx,coords):
    print coords, yes_no
    if yes_no == 'y':
        index = 0
        x = doc.tables[tableIdx].cell(coords[0],coords[1])._element.xpath('.//w:checkBox')
        x[index].append(checkedElement())
    elif yes_no == 'n':
        index = 1
        x = doc.tables[tableIdx].cell(coords[0],coords[1])._element.xpath('.//w:checkBox')
        x[index].append(checkedElement())
    else:
        print "value was neither yes or no"
        pass

这是我到目前为止编写的完整代码。我有一堆重构要做,但它现在工作得很好。我的 .docx 模板和字典 table1 和 table2 中有两个表包含单元格行和列坐标。此脚本用于使用 ESRI 的 Survey123 发布的数据填写所需的表格。

from docx import Document
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
import arcpy
import datetime
import os

table1 = {
    'BusinessName':[2,3],
    'LicenseNumber':[2,14],
    'OwnerName':[3,3],
    'PhoneNumber':[3,14],
    'BusinessAddress':[4,5],
    'County':[4,14],
    'City':[5,1],
    'St':[5,8],
    'Zip':[5,15],
    'LicenceExpired':[6,1], #CheckBox
    'DateExpired':[6,15],
    'LicenceRenewal':[7,1], #CheckBox
    'NumberDisplayed':[8,1], #CheckBox
    'NameAddDisplayed':[10,1], #CheckBox
    'VehicleInfoMatches':[12,1], #CheckBox
    'DischargeValveCapped':[14,1], #CheckBox
    'DischargeValveCapChained':[15,1], #CheckBox
    'HoseDisinfectCarried':[16,1], #CheckBox
    'VehicleAndTankClean':[17,1], #CheckBox
    'FreeOfLeaks':[18,1] #CheckBox
}

table2 = {
    'LandApplyWaste':[1,1], #Yes/No CheckBox
    'LocationDescriptionAccurate':[6,1], #Yes/No CheckBox
    'LocationDescriptionAccDesc':[6,5], #text
    'Slope':[7,1], #Yes/No CheckBox
    'DistanceNearestResidence':[8,1], #Yes/No CheckBox
    'DistanceNearestWell':[9,1], #Yes/No CheckBox
    'DistanceNearestStreamLakeEtc':[10,1], #Yes/No CheckBox
    'SeptageIncorporated':[11,1], #Yes/No CheckBox
    'InjectedIncorporated':[12,3], #Yes/No CheckBox, dependent on the septage incorporated being yes
    'SeptageStabilized':[13,1], #Yes/No CheckBox
    'HowIsLimeMixed':[14,3], #text dependent on if lime was used
    'ConfiningLayerOrGroundwater':[15,1], #Yes/No CheckBox
    'ConfiningLayerOrGroundwaterDesc':[16,3], #text
    'CropGrown':[17,1], #Yes/No CheckBox
    'CropGrownHowVerified':[19,3], #text
    'LandAppCompliance':[20,1], #Yes/No CheckBox
    'AdditionalComments':[22,3],
    'SignDate':[22,13]
}

def checkedElement():
    elm = OxmlElement('w:checked')
    elm.set(qn('w:val'),"true")
    return elm

def yesNoCheck(yes_no,tableIdx,coords):
    print coords, yes_no
    if yes_no == 'y':
        index = 0
        x = doc.tables[tableIdx].cell(coords[0],coords[1])._element.xpath('.//w:checkBox')
        x[index].append(checkedElement())
    elif yes_no == 'n':
        index = 1
        x = doc.tables[tableIdx].cell(coords[0],coords[1])._element.xpath('.//w:checkBox')
        x[index].append(checkedElement())
    else:
        print "value was neither yes or no"
        pass

def disposalMethodCheck(method, locationDec):
    vals = {
        'WastewaterTreatmentFacility':[20,1],
        'LandApplication':[22,1],
        'SanitaryLandfill':[24,1],
        'SeptageLagoonOrDryingBed':[26,1]
    }
    if method != None:
        row,col = vals[method]
        checkBoxElm = doc.tables[0].cell(row,col)._element.xpath('.//w:checkBox')[0]
        print "{0} Checked!".format(method)
        checkBoxElm.append(checkedElement())
        editTxt(locationDec,0,[row,6]) 

def editTxt(text, tblIdx, coords, alignment = WD_ALIGN_PARAGRAPH.LEFT, bold=True):
    print text, coords
    field = doc.tables[tblIdx].cell(coords[0],coords[1]).paragraphs[0]
    field.text = text
    field.alignment = alignment
    field.runs[0].font.bold = bold

def addSig(sigJpgPath):
    para = doc.tables[1].row_cells(23)[0].paragraphs[0]
    para.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = para.add_run()
    run.add_picture(sigJpgPath,width=Inches(1.34),height=Inches(.35))

fc = r"E:\PumperTruckInspectionFeatureClass"
arcpy.MakeFeatureLayer_management (fc, "PumperTruckInspections")
attach = r"PumperTruckInspection__ATTACH" #Where signatures are stored

def rows_as_dicts(cursor):
    colnames = cursor.fields
    for row in cursor:
        yield dict(zip(colnames, row))

def dateString(date):
    if date != None:
        d = date.strftime('%m/%d/%Y')
        return d
    else:
        print "no date"
        return ''

def checkBusName(name):
    if name != None:
        return name
    else:
        return 'unknown'

with arcpy.da.SearchCursor(fc, '*') as sc:
    for row in rows_as_dicts(sc):
        doc = Document(r"path\to\TEMPLATE.docx")

        t = datetime.datetime.now().strftime('%Y-%m-%d')
        newDocName = checkBusName(row['BusinessName']) + t + '.docx'


        editTxt(row['BusinessName'],0,table1['BusinessName'])
        editTxt(row['LicenseNumber'],0,table1['LicenseNumber'])
        editTxt(row['OwnerName'],0,table1['OwnerName'])
        editTxt(row['PhoneNumber'],0,table1['PhoneNumber'])
        editTxt(row['BusinessAddress'],0,table1['BusinessAddress'])
        editTxt(row['County'],0,table1['County']) 
        editTxt(row['City'],0,table1['City'])
        editTxt(row['St'],0,table1['St'])
        editTxt(row['Zip'],0,table1['Zip'])
        editTxt(dateString(row['DateExpired']),0,table1['DateExpired'])
        yesNoCheck(row['LicenceExpired'],0, table1['LicenceExpired'])

        yesNoCheck(row['LicenceRenewal'],0, table1['LicenceRenewal'])
        yesNoCheck(row['NumberDisplayed'],0, table1['NumberDisplayed'])
        yesNoCheck(row['NameAddDisplayed'],0, table1['NameAddDisplayed'])
        yesNoCheck(row['VehicleInfoMatches'],0, table1['VehicleInfoMatches'])
        yesNoCheck(row['DischargeValveCapped'],0, table1['DischargeValveCapped'])
        yesNoCheck(row['DischargeValveCapChained'],0, table1['DischargeValveCapChained'])
        yesNoCheck(row['HoseDisinfectCarried'],0, table1['HoseDisinfectCarried'])
        yesNoCheck(row['VehicleAndTankClean'],0, table1['VehicleAndTankClean'])
        yesNoCheck(row['FreeOfLeaks'],0, table1['FreeOfLeaks'])
        disposalMethodCheck(row['DisposalMethod'],row['DisposalLocation'])
        if row['DisposalMethod'] == 'LandApplication':
            yesNoCheck(row['LandApplyWaste'],1,table2['LandApplyWaste'])
            yesNoCheck(row['LocationDescriptionAccurate'],1,table2['LocationDescriptionAccurate'])
            editTxt(row['LocationDescriptionAccDesc'],1,table2['LocationDescriptionAccDesc'])
            yesNoCheck(row['Slope'],1,table2['Slope'])
            yesNoCheck(row['DistanceNearestResidence'],1,table2['DistanceNearestResidence'])

            yesNoCheck(row['DistanceNearestWell'],1,table2['DistanceNearestWell'])
            yesNoCheck(row['DistanceNearestStreamLakeEtc'],1,table2['DistanceNearestStreamLakeEtc'])
            yesNoCheck(row['SeptageIncorporated'],1,table2['SeptageIncorporated'])
            yesNoCheck(row['InjectedIncorporated'],1,table2['InjectedIncorporated']) #might need a new method since its not yes/no
            yesNoCheck(row['SeptageStabilized'],1,table2['SeptageStabilized'])
            editTxt(row['HowIsLimeMixed'],1,table2['HowIsLimeMixed'])
            yesNoCheck(row['ConfiningLayerOrGroundwater'],1,table2['ConfiningLayerOrGroundwater'])
            editTxt(row['ConfiningLayerOrGroundwaterDescript'],1,table2['ConfiningLayerOrGroundwaterDescript'])
            yesNoCheck(row['CropGrown'],1,table2['CropGrown'])
            editTxt(row['CropGrownHowVerified'],1,table2['CropGrownHowVerified'])
            yesNoCheck(row['LandAppCompliance'],1,table2['LandAppCompliance'])
        editTxt(row['AdditionalComments'],1,table2['AdditionalComments'],bold=False)
        where = "REL_GLOBALID = '{0}'".format(row['GlobalID'])
        from pprint import pprint
        with arcpy.da.SearchCursor(attach,['DATA', 'ATT_NAME', 'ATTACHMENTID'],where_clause=where) as cursor:
            for r in rows_as_dicts(cursor):
                pprint(r)
                name = r['ATT_NAME']
                attachment = r['DATA']
                if name.split('_')[0] == 'InspectorSignature':
                    imagePath = os.path.join(name.split('_')[0] + "_" + )
                    open(("sig.jpeg"), 'wb').write(attachment.tobytes())
                    addSig("sig.jpeg")

                    break

        editTxt(dateString(row['SignDate']),1,table2['SignDate'],alignment = WD_ALIGN_PARAGRAPH.CENTER,bold=False)
        doc.save(newDocName)
        del doc

关于python - 使用 docx 模块使用 Python 检查 .docx 形式的复选框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43619911/

相关文章:

python - 如何在 python 中创建菜单并使用函数作为我的选项?

hadoop - 寻找可以与 Hadoop 集成的 Geo Spatial Library

.net - 如何使用 ArcGIS .Net SDK 离线查询 DTED?

javascript - 如何防止 dynamicMapLayer 在每次缩放或平移 map 时刷新?

使用 GeoJson 时 Python 编译时错误

python - 如何计算 pandas 数据框中各列的非 NaN 值?

python - SQLAlchemy:一对一关系对象创建问题

python-2.7 - 类型错误 : Expected sequence or array-like, 得到了估算器

python - 是否可以在元组中使用 if ?

python - gunicorn + flask (connexion/swagger_server) 超时/不响应 API 请求