'''
注意事项:
1、流程图必须不包含合并单元格,一列对应一个访视,一行对应一个表单;
2、所需表单的单元格不为空即可,不需要的表单对应的单元格为空;
3、流程图中表单的顺序需要与unique CRF文件中表格的顺序一致,名称可以不一致;
4、程序会根据流程图第一行设置页眉中的访视信息,根据流程图第二行设置页眉中的时间窗信息,其余信息请添加在CRF文件最后一个表格中,作为页眉模板;
5、流程图A1单元格内容必须为“访视编号”;
6、用户界面中;流程图路径和CRF路径请输入完整的文件路径,包含文件拓展名;(也可点击按钮选取)
7、输出文件路径仅需文件夹路径,末尾不加’\‘;
8、输出文件中若某些表格无表框,可在原始CRF文件中将表格复制到excel中再复制回来,重新运行即可;建议直接在excel中构建CRF。不要使用特殊格式的表格;
9、页眉文字若出现粗细不一致,更改字体即可一致;
10、页码请单独添加;
11、若需横排页面请手动完成;
'''
#导入所需的库——————————————————————————————————————————
from copy import deepcopy #用于复制表格
from docx import Document #操作word文件
import docx #操作word文件
import copy
import pandas as pd #读取流程图文件
import tkinter as tk #构建用户界面
import tkinter.messagebox #输出弹窗
import threading #线程
from docx.shared import Cm #页眉格式
from docx.oxml.ns import qn #字体
from tkinter import filedialog,dialog
import os
#主函数-------------------------------------------------------------------------------------
mpath='NA'
cpath='NA'
opath='NA'
def met():
global mpath
mpath=filedialog.askopenfilename()
en1.insert('insert',mpath)
print(mpath)
def uniq():
global cpath
cpath=filedialog.askopenfilename()
en2.insert('insert',cpath)
def outf():
global opath
opath=filedialog.askdirectory()
en3.insert('insert',opath)
def thread_it(func, *args):
'''将函数打包进线程'''
# 创建
t = threading.Thread(target=func, args=args)
# 守护 !!!
t.setDaemon(True)
# 启动
t.start()
# 阻塞--卡死界面!
def getpath():
try: #用于输出错误信息
global mpath,cpath,opath,tel
mpath=en1.get() #获取流程图文件路径
cpath=en2.get() #获取CRF文件路径
opath=en3.get()+'\outfile.docx' #获取输出路径
print(mpath,cpath,opath)
#根据流程图构建每一个表单对应的序号的字典
metrics=pd.read_excel(mpath)
form={}
for i in range(len(metrics)):
if metrics['访视编号'][i] not in form.keys():
form[metrics['访视编号'][i]]=i
print(form)
#读取CRF文件,获取其中的表格
outfile=docx.Document()
filename=cpath
document=Document(filename)
tab=document.tables
#按流程列循环每一个访视
for i in metrics.columns:
print(i)
te1.insert('insert',i)
te1.insert('insert','\n')
te1.see('end')
if i=='访视编号':
continue
outfile.add_heading(i,level=1)
#如果某一访视某一表单对应的单元格内不为空,则将对应的表格添加到输出文件中
for n in range(1,len(metrics)):
if metrics[i][n]==metrics[i][n]:
te1.insert('insert',' '+metrics['访视编号'][n])
te1.insert('insert','\n')
te1.see('end')
outfile.add_heading(metrics['访视编号'][n],level=2)
table=tab[form[metrics['访视编号'][n-1]]]
newtable=deepcopy(table)
paragraph=outfile.add_paragraph()
paragraph._p.addnext(newtable._element)
outfile.add_page_break()
if i != metrics.columns[-1]: #如果不是最后一个访视,那么久在结尾添加分节符
outfile.add_section()
header_table = tab[-1]
visit=list(metrics.columns)
#将CRF文件中最后一个表格作为页眉模板,访视信息和时间窗根据流程图前两行获取
flag=0
for section in outfile.sections:
if flag !=0:
section.header.is_linked_to_previous=False
print('section{}'.format(flag))
header = section.header
header_table.cell(0,2).text=visit[flag+1]
header_table.cell(1,2).text=metrics[visit[flag+1]][0]
print(header_table.cell(0,2).text)
print(header_table.cell(1,2).text)
te1.insert('insert',header_table.cell(0,2).text)
te1.insert('insert',header_table.cell(1,2).text)
te1.insert('insert','\n')
te1.see('end')
new_table = deepcopy(header_table)
new_table.autofit = True
paragraph = header.paragraphs[0]
paragraph._p.addnext(new_table._element)
header.header_distance = Cm(1.2)
flag+=1
#设置文件字体为宋体
outfile.styles['Normal'].font.name = u'宋体'
outfile.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
#保存输出文件,弹窗提示运行完成
outfile.save(opath)
tk.messagebox.showinfo('提示','运行完成')
#若运行出错,输出报错信息
except Exception as e: te1.insert('insert',e)
#GUI界面-------------------------------------------------------------------------
window=tk.Tk()
window.geometry('800x500')
window.title('CRF排版')
bu2=tk.Button(window,text='点击选择流程图文件:',width=25,command=met)
bu2.grid(row=0,column=0)
en1=tk.Entry(window,width=70)
en1.grid(row=0,column=1)
bu3=tk.Button(window,text='点击选择Unique CRF文件:',width=25,command=uniq)
bu3.grid(row=1,column=0)
en2=tk.Entry(window,width=70)
en2.grid(row=1,column=1)
bu3=tk.Button(window,text='点击选择结果输出文件夹:',width=25,command=outf)
bu3.grid(row=2,column=0)
en3=tk.Entry(window,width=70)
en3.grid(row=2,column=1)
te1=tk.Text(window)
te1.grid(row=4,column=1)
bu1=tk.Button(window,text='运行程序',command=lambda:thread_it(getpath))
bu1.grid(row=3,column=1)
lab3=tk.Label(window,text='程序运行信息:')
lab3.grid(row=4,column=0)
window.mainloop()
05-14
07-09