| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """
- 旅检三部"三三"数字管理平台 Excel → SQL 导入脚本
- 运行: python excel_to_sql.py
- 输出: ledger_data_import.sql
- """
- import os, re, sys
- from datetime import datetime, date
- try:
- import openpyxl
- except ImportError:
- sys.exit("请先安装 openpyxl: pip install openpyxl")
- # ──────────────────────────────────────────────
- # 配置
- # ──────────────────────────────────────────────
- EXCEL_DIR = r'C:\Users\linzo\Downloads'
- OUTPUT_SQL = r'C:\Users\linzo\IdeaProjects\chongqing-server\sql\ledger_data_import.sql'
- BATCH_NO = datetime.now().strftime('BATCH_%Y%m%d_%H%M%S')
- CREATE_BY = 'admin'
- CREATE_TIME = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- # ──────────────────────────────────────────────
- # 工具函数
- # ──────────────────────────────────────────────
- def find_excel():
- for f in os.listdir(EXCEL_DIR):
- if '旅检' in f and f.endswith('.xlsx') and not f.startswith('~'):
- return os.path.join(EXCEL_DIR, f)
- raise FileNotFoundError('找不到 旅检*.xlsx 文件,请检查路径')
- def esc(v, maxlen=None):
- """转义 SQL 字符串值,可选最大长度截断"""
- if v is None:
- return 'NULL'
- s = str(v).strip()
- if s == '' or s == 'None':
- return 'NULL'
- s = s.replace('\\', '\\\\').replace("'", "\\'").replace('\n', '\\n').replace('\r', '').replace('\t', ' ')
- if maxlen and len(s) > maxlen:
- s = s[:maxlen]
- return f"'{s}'"
- def to_date(v):
- """将各种格式的日期转成 'YYYY-MM-DD' 或 NULL"""
- if v is None:
- return 'NULL'
- if isinstance(v, (datetime, date)):
- return f"'{v.strftime('%Y-%m-%d')}'"
- s = str(v).strip()
- if not s or s == 'None':
- return 'NULL'
- # 尝试多种格式
- for fmt in ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d', '%Y/%m/%d', '%m/%d/%Y'):
- try:
- return f"'{datetime.strptime(s.split('.')[0].strip(), fmt).strftime('%Y-%m-%d')}'"
- except ValueError:
- pass
- # 返回原始字符串(可能有特殊格式)
- return esc(s[:10])
- def to_decimal(v, default='NULL'):
- if v is None:
- return default
- s = str(v).strip().replace('¥', '').replace(',', '').strip()
- if not s or s == 'None':
- return default
- try:
- return str(float(s))
- except ValueError:
- return default
- def to_int(v, default='NULL'):
- if v is None:
- return default
- try:
- return str(int(float(str(v))))
- except (ValueError, TypeError):
- return default
- def row_vals(ws, row_num):
- """返回一行所有单元格值(列表)"""
- row = list(ws.iter_rows(min_row=row_num, max_row=row_num, values_only=True))
- return list(row[0]) if row else []
- def iter_data_rows(ws, header_row=2):
- """从 header_row+1 开始迭代有效数据行"""
- for row in ws.iter_rows(min_row=header_row + 1, values_only=True):
- # 跳过全空行
- if all(v is None or str(v).strip() == '' for v in row):
- continue
- yield list(row)
- def pad(lst, n):
- """把列表补齐到 n 长度"""
- return lst + [None] * max(0, n - len(lst))
- # ──────────────────────────────────────────────
- # 各 sheet 的映射函数
- # 每个函数返回 list of SQL INSERT 语句
- # ──────────────────────────────────────────────
- def sheet_supervision_problem(ws):
- """部门监察问题记录表 → ledger_supervision_problem
- Excel R2: 时间(0) 区域(1) 工作点(2) 岗位(3) 责任人(4) 问题描述(5)
- 问题类型(6) 整改措施(7) 依据(8) 问题层级(9) 班组(10)
- 队室质控员(11) 质控推送队室负责人(12) 附件(13) 整改情况(14)
- 佐证材料(15) 发送至相关人员(16) 本月内发生问题次数(17)
- 上月质控问题超过三次人员(18) 检查人员(19) 分管质控经理(20)
- 录入时间(21) 部门培训教员(22) 队室内勤(23) 队室负责人(24)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 25)
- stmts.append(
- f"INSERT INTO ledger_supervision_problem "
- f"(record_date,location,channel_no,inspected_name,problem_desc,problem_type,"
- f"result_handling,remark,team_name,inspector_name,evidence_file,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[0])},{esc(c[1])},{esc(c[2])},{esc(c[4])},{esc(c[5])},{esc(c[6])},"
- f"{esc(c[7])},{esc(c[8])},{esc(c[10])},{esc(c[11])},{esc(c[13])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_patrol_inspection(ws):
- """队室三级质控巡查记录表 → ledger_patrol_inspection
- Excel R2: 巡查日期(0) 巡查区域(1) 巡查工作点(2) 巡查时间段(3) 巡查岗位(4)
- 被检查人员(5) 有无问题(6) 检查情况描述(7) 类型(8) 整改措施(9)
- 附件(10) 整改情况(11) 佐证材料(12) 班组(13) 责任组长(14)
- 队室质控员(15) 队室负责人(16) 填报人(17) 队室内勤(18) 填报时间(19)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 20)
- stmts.append(
- f"INSERT INTO ledger_patrol_inspection "
- f"(record_date,location,channel_no,inspected_name,patrol_type,patrol_item,"
- f"problem_desc,result_handling,evidence_file,team_name,inspector_name,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[0])},{esc(c[1])},{esc(c[2])},{esc(c[5])},{esc(c[8])},{esc(c[4])},"
- f"{esc(c[7])},{esc(c[9])},{esc(c[10])},{esc(c[13])},{esc(c[14])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def _parse_datetime(v):
- """返回 (date_str, time_str) tuple for SQL"""
- if v is None:
- return 'NULL', 'NULL'
- if isinstance(v, datetime):
- return f"'{v.strftime('%Y-%m-%d')}'", f"'{v.strftime('%H:%M:%S')}'"
- s = str(v).strip()
- if not s or s == 'None':
- return 'NULL', 'NULL'
- for fmt in ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d'):
- try:
- dt = datetime.strptime(s.split('.')[0].strip(), fmt)
- return f"'{dt.strftime('%Y-%m-%d')}'", f"'{dt.strftime('%H:%M:%S')}'"
- except ValueError:
- pass
- return esc(s[:10]), 'NULL'
- def sheet_realtime_interception(ws):
- """部门实时质控拦截情况记录表 → ledger_realtime_interception
- Excel R2: 时间(0) 区域(1) 工作点(2) 岗位(3) 责任人(4) 实时质控拦截物品(5)
- 个数(6) 问题类型(7) 整改措施(8) 问题层级(9) 班组(10)
- 附件(11) 问题类别(12) 个人复盘(13) 队室复盘(14)
- 队室质控员(15) 质控推送队室负责人(16) 开机年限(17)
- 责任人开机年龄(18) 发送至相关人员(19)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 20)
- d, t = _parse_datetime(c[0])
- stmts.append(
- f"INSERT INTO ledger_realtime_interception "
- f"(record_date,record_time,channel_no,inspector_name,item_name,"
- f"item_quantity,item_category,handling_method,team_name,evidence_file,remark,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{d},{t},{esc(c[2])},{esc(c[4])},{esc(c[5])},"
- f"{to_int(c[6])},{esc(c[7])},{esc(c[8])},{esc(c[10])},{esc(c[11])},{esc(c[12])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_service_patrol(ws):
- """服务巡查 → ledger_service_patrol
- Excel R2: 时间(0) 区域(1) 工作点(2) 岗位(3) 责任人(4) 问题描述(5)
- 问题类型(6) 整改措施(7) 班组(8) 问题层级(9)
- 队室服务联络人(10) 服务推送队室负责人(11) 附件(12)
- 整改情况(13) 佐证材料(14) 发送至相关人员(15)
- 本月内发生问题次数(16) 检查人员(17) 分管服务经理(18) 队室内勤(19)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 20)
- stmts.append(
- f"INSERT INTO ledger_service_patrol "
- f"(record_date,location,inspected_name,problem_desc,service_type,"
- f"result_handling,team_name,evidence_file,inspector_name,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[0])},{esc(c[1])},{esc(c[4])},{esc(c[5])},{esc(c[6])},"
- f"{esc(c[7])},{esc(c[8])},{esc(c[12])},{esc(c[17])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_complaint(ws):
- """投诉情况 → ledger_complaint
- Excel R2: 时间(0) 航班号(1) 旅客姓名(2) 班组(3) 责任人(4)
- 投诉情况(5) 旅客诉求(6) 类别(7) 渠道来源(8)
- 是否有责(9) 处理进度(10) 责任队长(11) 队室内勤(12)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 13)
- stmts.append(
- f"INSERT INTO ledger_complaint "
- f"(record_date,flight_no,passenger_name,team_name,responsible_name,"
- f"complaint_desc,complaint_type,result_handling,remark,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[0])},{esc(c[1])},{esc(c[2])},{esc(c[3])},{esc(c[4])},"
- f"{esc(c[5])},{esc(c[7])},{esc(c[10])},{esc(c[8])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_security_test(ws):
- """安保测试记录表(部门)→ ledger_security_test
- Excel R2: 开展时间(0) 测试区域(1) 测试通道(2) 测试项目(3)
- 被测试人员(4) 被测试岗位(5) 测试物品(6) 开展项目图片或视频(7)
- 是否通过(8) 层级(9) 整改措施(10) 复查地点及时间(11)
- 整改材料(12) 班组(13) 推送队室质控员(14) 推送质控队长(15)
- 队室内勤(16) 点击推送至相关人员(17) 队室负责人(18)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 19)
- stmts.append(
- f"INSERT INTO ledger_security_test "
- f"(record_date,location,channel_no,test_item,tested_name,test_type,"
- f"evidence_file,test_result,result_handling,team_name,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[0])},{esc(c[1])},{esc(c[2])},{esc(c[3])},{esc(c[4])},{esc(c[6])},"
- f"{esc(c[7])},{esc(c[8])},{esc(c[10])},{esc(c[13])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_channel_pass_rate(ws):
- """通道过检率 → ledger_channel_pass_rate
- Excel R2: 组长(0) 班组(1) 队室内勤(2) 2026年1月平均过检率(3) 2026年2月...(4) 2026年3月...(5) ...
- 结构是 pivot:一行=一个班组,多列=多月;展开为多行
- """
- headers = row_vals(ws, 2)
- # 找月份列(列3起)
- month_cols = []
- for idx, h in enumerate(headers[3:], start=3):
- if h and str(h).strip():
- month_cols.append((idx, str(h).strip()))
- # 提取月份年份
- def parse_month(label):
- m = re.search(r'(\d{4})年(\d{1,2})月', label)
- if m:
- return f"{m.group(1)}-{int(m.group(2)):02d}-01"
- return None
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, len(headers) + 5)
- team = esc(c[1])
- for col_idx, label in month_cols:
- rate = to_decimal(c[col_idx] if col_idx < len(c) else None)
- if rate == 'NULL':
- continue
- month_date = parse_month(label)
- rec_date = f"'{month_date}'" if month_date else 'NULL'
- stmts.append(
- f"INSERT INTO ledger_channel_pass_rate "
- f"(record_date,team_name,pass_rate,remark,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{rec_date},{team},{rate},{esc(label)},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_unsafe_event(ws):
- """不安全事件 → ledger_unsafe_event
- Excel R2: 时间(0) 事件描述(1) 类别(2) 航班号(3) 责任人(4)
- 涉及班组(5) 涉及物品(6) 岗位(7) 区域(8) 通道号(9)
- 图像(10) 队室内勤(11)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 12)
- stmts.append(
- f"INSERT INTO ledger_unsafe_event "
- f"(record_date,event_desc,event_type,responsible_name,team_name,"
- f"evidence_file,remark,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[0])},{esc(c[1])},{esc(c[2])},{esc(c[4])},{esc(c[5])},"
- f"{esc(c[10])},{esc(c[8])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_seizure_stats(ws):
- """2026查获违规品统计 → ledger_seizure_stats
- Excel R2: 查获时间(0) 信息提取(1) 信息提取2(2) 部门/队室(3) 工作区域(4)
- 安检员(5) 安检资格证书等级(6) 岗位(7) 航班号(8) 目的地(9)
- 进/出港(10) 违规主体(11) 旅客姓名(12) 旅客性别(13) 旅客民族(14)
- 旅客年龄(15) 违规类别(16) 违规物品种类(17) 二级分类(18) 数量(19)
- ...(可能更多列)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 30)
- stmts.append(
- f"INSERT INTO ledger_seizure_stats "
- f"(record_date,team_name,inspector_name,flight_no,passenger_name,"
- f"item_category,item_name,item_quantity,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[0])},{esc(c[3])},{esc(c[5])},{esc(c[8])},{esc(c[12])},"
- f"{esc(c[16])},{esc(c[17])},{to_int(c[19])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_terminal_bonus(ws):
- """航站楼加分 → ledger_terminal_bonus
- Excel R2: 审核日期(0) 姓名(1) 班组(2) 加分分数(3) 队室内勤(4) 总加分数(5) 队室负责人(6)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 7)
- stmts.append(
- f"INSERT INTO ledger_terminal_bonus "
- f"(approve_date,person_name,team_name,add_score,remark,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[0])},{esc(c[1])},{esc(c[2])},{to_decimal(c[3],'0')},{esc(c[4])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_exam_score(ws):
- """成绩收集 → ledger_exam_score
- Excel R2: 类别(0) 期数(1) 考试人员(2) 理论成绩(3) 图像成绩(4) 班组(5) 分类(6) 备注(补考分数)(7) 队室教员(8)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 9)
- stmts.append(
- f"INSERT INTO ledger_exam_score "
- f"(exam_category,exam_period,person_name,score,team_name,remark,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{esc(c[0])},{esc(c[1])},{esc(c[2])},{to_decimal(c[3],'NULL')},{esc(c[5])},{esc(c[7])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_reward_approval(ws):
- """小额奖励审批单-安检-质控 → ledger_reward_approval
- 特殊:R1 就是表头(没有 title row)
- Excel R1: 员工编码(0) 姓名(1) 查获(事件)时间(2) 奖励类别(3) 查获物品(4)
- 类别(5) 奖励事由(安全)(6) 人员类别(7) 主要事由简述(8)
- 数据从 R2 开始
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=1): # header_row=1 means data from row 2
- c = pad(cols, 9)
- stmts.append(
- f"INSERT INTO ledger_reward_approval "
- f"(approve_date,person_name,reward_type,approval_status,remark,"
- f"import_batch,source_type,create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[2])},{esc(c[1])},{esc(c[3])},'待审批',{esc(c[8])},"
- f"'{BATCH_NO}','1','{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_reward_penalty(ws):
- """部门奖惩记录表 → ledger_reward_penalty
- Excel R2: 姓名(0) 班组(1) 事由(2) 扣罚金额(3) 最后更新时间(4)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 5)
- # 扣罚金额转为负数分值(仅金额,非分值,存为负数)
- amt = to_decimal(c[3], 'NULL')
- score_change = f"-{amt}" if amt != 'NULL' else 'NULL'
- stmts.append(
- f"INSERT INTO ledger_reward_penalty "
- f"(record_date,person_name,team_name,type,event_desc,score_change,"
- f"create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[4])},{esc(c[0])},{esc(c[1])},'2',{esc(c[2])},{score_change},"
- f"'{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_leave_special(ws):
- """请、休假记录表(特殊)→ ledger_leave_special
- Excel R2: 姓名(0) 班组(1) 时间(起)(2) 时间(止)(3) 休假类别(4) 天数/时长(5)
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 6)
- stmts.append(
- f"INSERT INTO ledger_leave_special "
- f"(person_name,team_name,leave_type,start_date,end_date,days,"
- f"create_by,create_time,del_flag) VALUES ("
- f"{esc(c[0])},{esc(c[1])},{esc(c[4])},{to_date(c[2])},{to_date(c[3])},{to_decimal(c[5],'NULL')},"
- f"'{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- def sheet_banner_letter(ws):
- """锦旗及感谢信 → ledger_banner_letter
- Excel R2: 时间(0) 姓名(1) 获得感谢信的具体内容(2) 类别(3) 图片和附件(4) 班组(5) 队室内勤(6)
- 类别: 感谢信→'2', 锦旗→'1', 其他→'2'
- """
- stmts = []
- for cols in iter_data_rows(ws, header_row=2):
- c = pad(cols, 7)
- typ = '1' if str(c[3] or '').strip() in ('锦旗',) else '2'
- stmts.append(
- f"INSERT INTO ledger_banner_letter "
- f"(record_date,person_name,content_desc,type,evidence_file,team_name,remark,"
- f"create_by,create_time,del_flag) VALUES ("
- f"{to_date(c[0])},{esc(c[1])},{esc(c[2])},'{typ}',{esc(c[4])},{esc(c[5])},{esc(c[6])},"
- f"'{CREATE_BY}','{CREATE_TIME}','0');"
- )
- return stmts
- # ──────────────────────────────────────────────
- # sheet name → handler mapping
- # ──────────────────────────────────────────────
- SHEET_MAP = {
- '部门监察问题记录表': ('ledger_supervision_problem', sheet_supervision_problem),
- '队室三级质控巡查记录表': ('ledger_patrol_inspection', sheet_patrol_inspection),
- '部门实时质控拦截情况记录表': ('ledger_realtime_interception', sheet_realtime_interception),
- '服务巡查': ('ledger_service_patrol', sheet_service_patrol),
- '投诉情况': ('ledger_complaint', sheet_complaint),
- '安保测试记录表(部门)': ('ledger_security_test', sheet_security_test),
- '通道过检率': ('ledger_channel_pass_rate', sheet_channel_pass_rate),
- '不安全事件': ('ledger_unsafe_event', sheet_unsafe_event),
- '2026查获违规品统计': ('ledger_seizure_stats', sheet_seizure_stats),
- '航站楼加分': ('ledger_terminal_bonus', sheet_terminal_bonus),
- '成绩收集': ('ledger_exam_score', sheet_exam_score),
- '小额奖励审批单-安检-质控': ('ledger_reward_approval', sheet_reward_approval),
- '部门奖惩记录表': ('ledger_reward_penalty', sheet_reward_penalty),
- '请、休假记录表(特殊)': ('ledger_leave_special', sheet_leave_special),
- '锦旗及感谢信': ('ledger_banner_letter', sheet_banner_letter),
- }
- SKIP_SHEETS = {
- '旅检三部人员信息表', '日常培训记录', '组长履职情况记录表',
- '健康锐兵(2026_3)', '宿舍消防安全专项自查表(部门)', '培训台账问题通报',
- }
- # ──────────────────────────────────────────────
- # 主程序
- # ──────────────────────────────────────────────
- def main():
- excel_path = find_excel()
- print(f'读取文件: {excel_path}')
- wb = openpyxl.load_workbook(excel_path, read_only=True, data_only=True)
- lines = [
- '-- =============================================',
- f'-- 台账数据导入 SQL 批次: {BATCH_NO}',
- f'-- 生成时间: {CREATE_TIME}',
- f'-- 来源文件: {os.path.basename(excel_path)}',
- '-- =============================================',
- 'SET NAMES utf8mb4;',
- 'SET FOREIGN_KEY_CHECKS=0;',
- '',
- ]
- total = 0
- for sheet_name in wb.sheetnames:
- if sheet_name in SKIP_SHEETS:
- print(f' [跳过] {sheet_name}')
- continue
- if sheet_name not in SHEET_MAP:
- print(f' [未映射] {sheet_name}')
- continue
- table_name, handler = SHEET_MAP[sheet_name]
- ws = wb[sheet_name]
- try:
- stmts = handler(ws)
- except Exception as e:
- print(f' [ERROR] {sheet_name}: {e}')
- import traceback; traceback.print_exc()
- stmts = []
- lines.append(f'-- ── {sheet_name} → {table_name} ({len(stmts)} 行) ──')
- lines.extend(stmts)
- lines.append('')
- total += len(stmts)
- print(f' [OK] {sheet_name} → {table_name}: {len(stmts)} 条')
- lines.append('SET FOREIGN_KEY_CHECKS=1;')
- lines.append(f'-- 共生成 {total} 条 INSERT 语句')
- wb.close()
- with open(OUTPUT_SQL, 'w', encoding='utf-8') as f:
- f.write('\n'.join(lines))
- print(f'\n✅ 完成!共 {total} 条,已写入:\n {OUTPUT_SQL}')
- print(f'\n执行方式(在 MySQL 客户端中):')
- print(f' USE chongqing; -- 替换为你的库名')
- print(f' SOURCE {OUTPUT_SQL.replace(chr(92), "/")};')
- if __name__ == '__main__':
- main()
|