昨天看到同事在手动整理excel报表,记录医师的挂号量,一天一天导出感觉很辛苦。
我想着写个程序帮助他,正好也自己对于整理excel相关的库比较感兴趣,游览了一些网址和博客后,决定使用xlrd和xlwt来实现整个过程。
其实整个流程很简单,就是从医院系统里下载固定模式的表格,然后把他整理到目标表格里,体现出每个医生每天的挂号率。
花了2小时写出来的代码,第一次使用excel相关库,分享给大家:
#!/bin/python3
# Created by Clancy
print("程序正在运行中,请稍后........")
import xlrd
import xlwt
from xlutils.copy import copy
import os
from pathlib import Path
original_path = './输入'
target_path = './模板'
original_files = os.listdir(original_path)
target_file = '模板.xls'
target_book = xlrd.open_workbook(Path(target_path, target_file), formatting_info=True)
target_data = target_book.sheets()[0]
new_book = copy(target_book)
new_sheet = new_book.get_sheet(0)
for i in range(len(original_files)):
# 读取原始表格和目标表格
file_name = original_files[i].split('.')[0]
orig_book = xlrd.open_workbook(Path(original_path, original_files[i]), formatting_info=True)
orig_data = orig_book.sheets()[0]
# 获取原始表格和模板表格的医师名字
doctor_orig_list = [str(orig_data.cell_value(k, 2)) for k in range(orig_data.nrows)] #原始表格医师名字
doctor_target_list = [str(target_data.cell_value(0, k)) for k in range(target_data.ncols)] #模板表格医师名字
for ii in range(1, len(doctor_target_list)):
new_sheet.write(i+1, 0, file_name) #文件名录入
# 名字会出现0次,1次,2次
if doctor_orig_list.count(target_data.cell_value(0, ii)) == 0 :
continue
else :
location_much = [ ]
for index, name in enumerate(doctor_orig_list):
if name == target_data.cell_value(0, ii):
location_much.append(index)
value = [ ]
for iii in range(len(location_much)):
jizhenhao = orig_data.cell_value(location_much[iii], 3)
putonghao = orig_data.cell_value(location_much[iii], 5)
jiarihao = orig_data.cell_value(location_much[iii], 7)
fuzhurenhao = orig_data.cell_value(location_much[iii], 9)
fuzhurenjiarihao = orig_data.cell_value(location_much[iii], 11)
ertongfengbihao = orig_data.cell_value(location_much[iii], 13)
total = jizhenhao + putonghao + jiarihao + fuzhurenhao + fuzhurenjiarihao + ertongfengbihao
value.append(total)
new_sheet.write(i+1, ii, sum(value))
new_book.save("本次导出.xls")
# 求和
sum_sheet = xlrd.open_workbook("本次导出.xls").sheets()[0]
for k in range(1,sum_sheet.nrows):
sum = 0
for kk in range(1,sum_sheet.ncols-1):
if sum_sheet.cell_value(k,kk) != '' :
sum += sum_sheet.cell_value(k,kk)
new_sheet.write(k, 52, sum)
new_book.save("本次导出.xls")
print("恭喜,本次导出完成 !")
os.system('pause')
# end this script
# created by Clancy in Beijing
调试了两次,出来的结果都正确,比较满意,唯一要吐槽的是xlwt有点难用,没有显示cell的功能,挺无语的,所以只能先读取再求和,感觉其实这一步稍微麻烦了点。
下次准备去试试xwings了,听说这个比较好用,xlwt还是难用,xlrd倒还是可以。
考虑到同事对于编程一窍不通,所以需要把这个脚本打包起来,点击就能用,所以最后加了一句os.system(‘pause’)。打包程序使用的是pyinstaller,不过这里有个问题,就是我的电脑是window10,而同事用的单位电脑,是windows7,涉及到跨平台和依赖库的问题。
打包过程很顺利,
pyinstaller -F -w -i logo.ico main.py
-F是生成单个exe文件,-D是生成多个文件(貌似多个文件运行速度比单个文件快),-w是去掉运行时候的黑框。
然后把生成的dict文件下的exe文件放到同事电脑里,当然意料之中的报错了,双击exe,程序一直闪退,也没有结果文件生成。把exe丢进cmd,就提示了报错的原因,问题是缺少win-xxx-1.1.dll,这个比较好解决,直接去网上下载就好。
为了避免一直出现window.dll相关的版本错误,我重新运行了打包程序:
pyinstaller --clean --win-private-assemblies -F -D -i logo.ico main.py
然后我把dict下面所有的dll都放进了c:/windows/system32下面,再次运行又闪退,然后重复上次操作寻找报错信息:
error loading python dll loadlibray pyinstaller: formatmessageW failed.
一开始我以为是缺少python39.dll文件,于是我在https://www.dll-files.com/python39.dll.html下载了dll放进system32下,结果发现这里面其实已经有python39.dll了。我又安装了VC++2015,vsvc_redist.x64.exe,还是不行。
这个时候感觉问题没那么简单,于是我仔细看了下报错信息:
Error loading Python DLL
C:\Users\xx\AppData\Local\Temp\XXX\python39.dll
然后我去网上搜了下原因,尝试了好些方法都无效。
无奈,我就把这个问题放在了作者github上的项目里去询问,https://github.com/pyinstaller/pyinstaller/discussions,等待作者回复。
(后续更新)
更新:
我刚把问题放上去,作者团队在几分钟内就回复我了,真的是太感谢了。
解决方法就是在conda里创建python3.8的虚拟环境,然后重新用pyinstaller打包,然后就完美运行在window7上了。
Much thanks to author rokm.
总结:对于window10,使用python3.9;对于医院、事业单位这样的陈旧机器,window7 只适用 python3.8或更老的版本。
希望这次分享能帮助到大家。