Python通过读取excel数据处理后导入到数据库表中
配置文件
# 数据库连接
[database]
DRIVER = {ODBC Driver 13 for SQL Server}
SERVER = 192.168.xxx.xx
# DATABASE = db_20230407
DATABASE = db
UID = sa
PWD = aaaaaaa
# excel文件路径
[filepath]
Adr = g:\drb\医保三目录202301111版a.xlsx
# 对应表名
[table]
西药中成药 = hbsyb_xcy_bzk
中药饮片 = hbsyb_zyyp_bzk
中药配方颗粒 = hbsyb_zypfkl_bzk
诊疗项目 = hbsyb_zl_bzk
材料 = hbsyb_cl_bzk
单件 = hbsyb_djcl_bzk
# 表对应的字段名
[西药中成药]
药品代码 = YBDM
注册名称 = ZCMC
商品名称 = SPMC
注册剂型 = zcjx
实际剂型 = sjjx
注册规格 = zcgg
实际规格 = sjgg
包装材质 = bzcz
最小包装数量 = zxbzsl
最小制剂单位 = zxzjdw
最小包装单位 = zxbzdw
药品企业 = ypscqy
上市药品持有人 = ssypcyr
批准文号 = pzwh
药品本位码 = ypbwm
市场状态 = sc_state
医保药品名称 = ybypmc
甲乙丙类标识 = ybbxdj
协议期内谈判药品标识 = tp_xyq_bs
谈判药品协议有效期起始日期 = tp_xyq_ksrq
谈判药品协议有效期截止日期 = tp_xyq_zzrq
限定支付范围药品自费标识 = xdzffwbs
医保支付标准(最小制剂单位) = ybzfbz_zxzjdw
医保支付标准(最小包装单位) = ybzfbz_zxbzdw
数据来源 = sjly
修改字段 = xgzd
谈判药医保支付标准(最小包装单位) = tpyzfbz_zxbzdw
集采药品医保支付标准 = ybzfbz
“两病”用药医保支付标准 = eb_yyzfbz
是否按特药门诊结算(享受“单独支付”待遇) = if_tyzf
是否三定管理 = ifsdgl
变更日志 = bqbgrz
是否试点药品(527) = ifsdyp
[中药饮片]
国家中药饮片代码 = ybdm
中药饮片名称 = zcmc
药材名称 = ycmc
炮制方法 = pzff
功效分类 = gxfl
药材科(族)来源 = ycly
药材种来源 = yczl
药用部位 = yybw
性味与归经 = xwgj
功能与主治 = gnzz
用法与用量 = yfyl
医保支付政策 = ybzfzc
甲乙丙类标识 = ybbxdj
数据来源 = sjly
[单件]
耗材代码 = ybdm
一级分类 = yjfl
二级分类 = ejfl
三级分类 = sjfl
医保通用名 = yb_tym
材质 = cz
特征 = tz
耗材企业 = scqy
注册证号 = zczh
[中药配方颗粒]
中药配方颗粒代码 = ybdm
中药配方颗粒名称 = zcmc
规格 = zcgg
包装规格 = bzgg
中药配方颗粒执行标准 = zypfbz
执行标准(国标/省标) = bzlx
保质期 = bzq
最小计价计量单位 = zxjjdw
不良反应监测信息 = blfyyjcxx
上市备案号 = ssbah
上市备案时间 = ssbasj
上市备案状态 = ssbazt
上市备案省局 = ssbasj1
生产企业 = scqy
生产地址 = scdz
销往省份 = xwsf
中药饮片代码 = zyypdm
中药饮片名称 = zyypmc
中药饮片执行标准 = zyypbz
医保类别 = ybbxdj
数据来源 = sjly
支付政策 = ybzfzc
[诊疗项目]
国家医疗服务项目代码 = ybdm
国家医疗服务项目名称 = ybmc
地方医疗服务项目代码 = df_ybdm
地方医疗服务项目名称 = df_mc
项目内涵 = xmlh
除外内容 = cwnr
计价单位 = jjdw
项目说明 = xmsm
政策标识 = zcbs
备注 = beizhu
一级 = gl_1
二级 = gl_2
三级 = gl_3
部属 = gl_bs
原编码 = y_ybbm
变更日志 = bgrz
[材料]
耗材代码 = ybdm
一级分类 = yjfl
二级分类 = ejfl
三级分类 = sjfl
医保通用名 = yb_tym
材质 = cz
特征 = tz
耗材企业 = scqy
政策标识区 = ybzfzc
注册证号 = zczh
耗材类型 = hclx
数据来源 = sjly
变更日志 = bgrz
属类代码 = sldm
置换材料分类 = zhclfl
运行代码
import xlwings as xs
import os
# import pandas as pd
import pyodbc
from openpyxl import load_workbook
import sys
import re
import configparser
class Main(object):
def __init__(self):
# Excel所在路径
config = configparser.ConfigParser()
config.read(r'excel_config.ini', encoding="utf-8")
# config.read('excel_config.ini')
Adr = config.get(r'filepath', 'Adr')
tab_jl = config.options('table')
# print(tab_jl)
# Adr = r"g:\liujun\drb\医保三目录202301111版a.xlsx"
# 定义正则表达式
pattern = r'\d+'
# 匹配字符串中的数字
match_ver = re.findall(pattern, Adr)
# print(match_obj)
wb = load_workbook(filename=Adr)
# 获取所有的表名
sheet_names = wb.sheetnames
# print(sheet_names)
# 打印所有的表名
for sheet_name in sheet_names:
for tab_value in tab_jl:
if tab_value in sheet_name and tab_value == '西药中成药':
sh = sheet_name # 待处理的表名
Tbn = config.get(r'table', tab_value)
Dic = self.Excel_MySQL_Columns(config, tab_value)
# print(Dic, 1)
self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
# if tab_value in sheet_name and tab_value == '中药饮片':
# sh = sheet_name # 待处理的表名
# Tbn = config.get(r'table', tab_value)
# Dic = self.Excel_MySQL_Columns(config, tab_value)
# self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
# if tab_value in sheet_name and tab_value == '中药配方颗粒':
# sh = sheet_name # 待处理的表名
# Tbn = config.get(r'table', tab_value)
# Dic = self.Excel_MySQL_Columns(config, tab_value)
# self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
# if tab_value in sheet_name and tab_value == '诊疗项目':
# sh = sheet_name # 待处理的表名
# Tbn = config.get(r'table', tab_value)
# Dic = self.Excel_MySQL_Columns(config, tab_value)
# self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
# if tab_value in sheet_name and tab_value == '材料':
# sh = sheet_name # 待处理的表名
# Tbn = config.get(r'table', tab_value)
# Dic = self.Excel_MySQL_Columns(config, tab_value)
# self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
# if tab_value in sheet_name and tab_value == '单件':
# sh = sheet_name # 待处理的表名
# Tbn = config.get(r'table', tab_value)
# # print(Tbn, sh)
# Dic = self.Excel_MySQL_Columns(config, tab_value)
# # print(Dic, 2)
# self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
wb.close()
def conn(self, config):
DRIVER = config.get('database', 'DRIVER')
SERVER = config.get('database', 'SERVER')
DATABASE = config.get('database', 'DATABASE')
UID = config.get('database', 'UID')
PWD = config.get('database', 'PWD')
# print(DRIVER, SERVER, DATABASE, UID, PWD)
conn = pyodbc.connect(
f'DRIVER={DRIVER}; SERVER={SERVER}; DATABASE={DATABASE}; UID={UID}; PWD={PWD}')
return conn
def Excel_Insert_MySQL(self, adr, sh, dic, tbn, match_ver, config):
app = xs.App(visible=False, add_book=False)
# print(adr)
app.screen_updating = False
app.display_alerts = False
# 打开工作簿
wb = app.books.open(adr, read_only=True)
sh = wb.sheets(sh)
# 统计sh中行数
nr = sh.used_range.last_cell.row + 1 # 增加1行以防止最后一行被丢弃处理
# 统计sh中列数
nc = sh.used_range.last_cell.column
# print(nr, nc)
i = 1
# 查找Excel与数据库中表对应的列
while i < nc:
rv = sh.range((i, 1), (i, nc)).value
# print(rv)
# 创建一个空字典,用于存储每列所在的位置
title_dic = {}
for k in dic:
# print(rv)
if k in rv:
# print(k)
title_dic.update({dic[k]: rv.index(k)})
# 如果在Excel中只找到了一列或部分列,则提示,并退出循环
# print(title_dic)
if len(title_dic) > 1 and len(title_dic) != len(dic):
print('请核查列名,是否与Excel中一致。')
print(title_dic.keys())
print(dic.values())
break
# 退出程序
sys.exit(1)
# 关闭工作簿
wb.close()
# 关闭Excel应用程序
app.quit()
# 判断要查找的列是否都在Excel中找到
# print(len(title_dic) == len(Dic))
if len(title_dic) == len(dic):
# 将标题行所在行数,赋值给sr
sr = i
break
i += 1
# 增加类别代码及版本号
dic['lbdm'] = 'LBDM'
dic['ver'] = 'ver'
if tbn == 'hbsyb_xcy_bzk':
Lbdm = 'XCY'
if tbn == 'hbsyb_cl_bzk':
Lbdm = 'cl'
if tbn == 'hbsyb_djcl_bzk':
Lbdm = 'djcl'
if tbn == 'hbsyb_zl_bzk':
Lbdm = 'zl'
if tbn == 'hbsyb_zypfkl_bzk':
Lbdm = 'kl'
if tbn == 'hbsyb_zyyp_bzk':
Lbdm = 'zyyp'
# 创建数据库链接
# print(sr)
try:
conn = self.conn(config)
cur = conn.cursor()
except Exception as e:
print(e)
# 创建追加插入sql语句
sql = f"insert into {tbn} (" + ','.join(list(dic.values())) + ") values (" + ','.join(['?'] * len(dic)) + ")"
# 从收入数据开始行读取
# print(sql)
i = sr + 1
# 插入成功行数
i1 = 0
# print(nr)
while i < nr:
rv = sh.range((i, 1), (i, nc)).value
Arr = []
# 建立集合
list1 = []
for k in title_dic.values():
if rv[k] is not None:
if len(str(rv[k])) >= 250:
value_new = rv[k].replace(" ", "")[:200]
else:
value_new = rv[k]
else:
value_new = rv[k]
Arr.append(value_new)
# 集合添加数据
list1.append(rv[k])
# print(list1, 'aa')
# print(len(list1) == len(title_dic), 1)
if len(list1) == len(title_dic): # 判断集合数量是否添加完毕
# print(list1[0], i)
# i1 += 1
# 判断第一个是否为空 为空则赋值
if list1[0] is None:
# print(list1[0], 2)
insert_flag = True
list1.clear()
else:
insert_flag = False
list1.clear()
# print(insert_flag, 3)
else:
insert_flag = False
# list1.clear()
# 终止循环
# print(insert_flag, 3)
# print(insert_flag)
# 防止空行导入数据
if insert_flag is True:
break
if insert_flag is False:
# print(i, )
Arr.append(Lbdm)
Arr.append("".join(match_ver)) # 将list数据转成字符串
# Arr = str(Arr)
# print(sql, Arr)
# 调用SQL
try:
cur.execute(sql, Arr)
# print(res.fetchone())
# cur.executemany(sql, Arr)
# 执行操作
conn.commit()
suc_fail = Falsealse
except Exception as e:
suc_fail = True
error = e
if suc_fail is True:
break
i += 1
i1 += 1
cur.close()
conn.close()
if suc_fail:
print(f'共【{nr - 1}】条,插入【{Lbdm}】数据失败,失败原因:', error)
else:
print(f'共【{nr-1}】条,成功插入【{Lbdm}】数据【{i1}】条')
# 关闭工作簿
wb.close()
# 关闭Excel应用程序
app.quit()
def Excel_MySQL_Columns(self, config, tab_value):
# 创建Excel列与MySQL数据库中表列之间的对应关系,Excel中列为键,MySQL中列为值
# sheet = wb.get_sheet_by_name(sh)
# column_names = []
dic = {}
if tab_value == '单件':
for values in config.options(tab_value):
dic[values] = config.get(tab_value, values)
if tab_value == '西药中成药':
for values in config.options(tab_value):
dic[values] = config.get(tab_value, values)
if tab_value == '中药饮片':
for values in config.options(tab_value):
dic[values] = config.get(tab_value, values)
if tab_value == '中药配方颗粒':
for values in config.options(tab_value):
dic[values] = config.get(tab_value, values)
if tab_value == '诊疗项目':
for values in config.options(tab_value):
dic[values] = config.get(tab_value, values)
if tab_value == '材料':
for values in config.options(tab_value):
dic[values] = config.get(tab_value, values)
# print(dic)
return dic
if __name__=='__main__':
Main()
以上代码python3.6运行通过