前段时间在公众号(后面会放上公众号和交流群的二维码)上面看到一篇介绍docxtpl的文章,同时也结合了下我们干农经权中签订合同里面的内容,就想着实现以一下,下面说一下实现的步骤:
第一步,先制作word模板,在模板制作过程中一定要在英文状态下输入大括号,制作一个例子如下图(1)所示:
第二步,代码实现,直接放入代码如下:
from docxtpl import DocxTemplate
import xlrd
def readXlsx(fileName): #读取excel里面的数据
workbook=xlrd.open_workbook(filename=fileName) #打开excel
booksheet=workbook.sheet_by_index(0)
nrows=booksheet.nrows
i=1
while(i snumber=i pd=1 list1=[] tstr1=str(booksheet.cell_value(snumber,1)) list1.append(tstr1) suma=0.0 #小计面积 while(pd): if booksheet.cell_value(snumber,0)==booksheet.cell_value(snumber+1,0): #相同的承包放在同一个列表中 dkmc=booksheet.cell_value(snumber,2) dkbm=booksheet.cell_value(snumber,3) dz=booksheet.cell_value(snumber,4) xz=booksheet.cell_value(snumber,5) nz=booksheet.cell_value(snumber,6) bz=booksheet.cell_value(snumber,7) mj=booksheet.cell_value(snumber,8) zl=booksheet.cell_value(snumber,9) str1=dkmc+";"+dkbm+";"+dz+";"+xz+";"+nz+";"+bz+";"+mj+";"+zl #连接地块的相关信息 list1.append(str1) if snumber+2==nrows: #避免超出excel最大索引 zdkmc=booksheet.cell_value(snumber+1,2) zdkbm=booksheet.cell_value(snumber+1,3) zdz=booksheet.cell_value(snumber+1,4) zxz=booksheet.cell_value(snumber+1,5) znz=booksheet.cell_value(snumber+1,6) zbz=booksheet.cell_value(snumber+1,7) zmj=booksheet.cell_value(snumber+1,8) zzl=booksheet.cell_value(snumber+1,9) str1=zdkmc+";"+zdkbm+";"+zdz+";"+zxz+";"+znz+";"+zbz+";"+zmj+";"+zzl #连接地块的相关信息 list1.append(str1) lasta=round(float(booksheet.cell_value(snumber+1,8)),2) #求出表格中最后一个面积 lastTwoa=round(float(booksheet.cell_value(snumber,8)),2) #求出表格中倒数第二个面积 suma=suma+lasta+lastTwoa #面积汇总 suma=round(suma,2) list1.append(suma) fileName=booksheet.cell_value(snumber+1,0) datachuli(fileName,list1) snumber=snumber+2 pd=0 continue suma=suma+float(booksheet.cell_value(snumber,8)) snumber=snumber+1 pd=1 else: dkmc=booksheet.cell_value(snumber,2) dkbm=booksheet.cell_value(snumber,3) dz=booksheet.cell_value(snumber,4) xz=booksheet.cell_value(snumber,5) nz=booksheet.cell_value(snumber,6) bz=booksheet.cell_value(snumber,7) mj=booksheet.cell_value(snumber,8) zl=booksheet.cell_value(snumber,9) str1=dkmc+";"+dkbm+";"+dz+";"+xz+";"+nz+";"+bz+";"+mj+";"+zl #连接地块的相关信息 list1.append(str1) if snumber+2==nrows: #处理最后一条与倒数第二条不同情况下运行 list2=[] suma1=0.0 #面积汇总 tstr2=str(booksheet.cell_value(snumber+1,1)) list2.append(tstr2) zdkmc=booksheet.cell_value(snumber+1,2) zdkbm=booksheet.cell_value(snumber+1,3) zdz=booksheet.cell_value(snumber+1,4) zxz=booksheet.cell_value(snumber+1,5) znz=booksheet.cell_value(snumber+1,6) zbz=booksheet.cell_value(snumber+1,7) zmj=booksheet.cell_value(snumber+1,8) zzl=booksheet.cell_value(snumber+1,9) str2=zdkmc+";"+zdkbm+";"+zdz+";"+zxz+";"+znz+";"+zbz+";"+zmj+";"+zzl #连接地块的相关信息 list2.append(str2) suma1=suma1+float(booksheet.cell_value(snumber+1,8)) suma1=round(suma1,2) list2.append(suma1) fileName=booksheet.cell_value(snumber+1,0) datachuli(fileName,list2) suma=suma+float(booksheet.cell_value(snumber,8)) suma=round(suma,2) list1.append(suma) fileName=booksheet.cell_value(snumber,0) datachuli(fileName,list1) snumber=snumber+2 pd=0 continue suma=suma+float(booksheet.cell_value(snumber,8)) suma=round(suma,2) list1.append(suma) fileName=booksheet.cell_value(snumber,0) datachuli(fileName,list1) pd=0 snumber=snumber+1 i=snumber def datachuli(fileName,data): #处理word模板数据 path='d:\\合同模板.docx' tp=DocxTemplate(path) dict2={} i=len(data) snb=1 enb=i-2 datalist2=[] while(snb<=enb): datalist=[] dict1={} datalist=str(data[snb]).split(';') dict1['dkmc']=datalist[0] dict1['dkbm']=datalist[1] dict1['dz']=datalist[2] dict1['nz']=datalist[3] dict1['xz']=datalist[4] dict1['bz']=datalist[5] dict1['mj']=datalist[6] dict1['zl']=datalist[7] datalist2.append(dict1) snb=snb+1 dict2['alerts']=datalist2 dict2['cname']=data[0] dict2['area']=data[i-1] context=dict2 tp.render(context) savePath='d:\\22\\'+fileName+".docx" tp.save(savePath) if __name__=='__main__': filename="d:\\test.xlsx" readXlsx(filename) 主要是根据上面模板写了一个简单测试,具体还根据大家的实际项目做相应调整。想了解更多可以多看看网上不同类型的文章介绍。 上面我是根据我自己所在的行业进行的应用,大家自由发挥。 感觉可以的话欢迎关注公众号: 有问题也可以加微信:第三步最后实现效果如下图: