前段时间在公众号(后面会放上公众号和交流群的二维码)上面看到一篇介绍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<nrows):
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)
主要是根据上面模板写了一个简单测试,具体还根据大家的实际项目做相应调整。想了解更多可以多看看网上不同类型的文章介绍。
第三步最后实现效果如下图:


上面我是根据我自己所在的行业进行的应用,大家自由发挥。
感觉可以的话欢迎关注公众号:

有问题也可以加微信:

网友评论