import pymysql import openpyxl from openpyxl.styles import Font, PatternFill, Alignment, Border, Side # ==================== 数据库配置 ==================== DB_CONFIG = { "host": "192.168.10.100", "port": 3308, "user": "root", "password": "Aa135790123", "database": "cqyt_new_prod", "charset": "utf8mb4", } OUTPUT_FILE = "export_medical_to_excel.xlsx" # 需要导出的表名列表(来自 mysql表名.txt) TARGET_TABLES = [ "medical_announcement_info", "medical_banner", "medical_check_package", "medical_check_package_item", "medical_conclusion", "medical_defend_cancer_code", "medical_depart_hospital", "medical_diseases_dic", "medical_diseases_dic_rel", "medical_doctor_check_item", "medical_doctor_sign", "medical_emp_defend_cancer", "medical_emp_occup_import", "medical_emp_occupational", "medical_health_check_statistics", "medical_health_check_statistics_info", "medical_hospital", "medical_hospital_area", "medical_hospital_doctor_check", "medical_hospital_emp", "medical_hospital_except_count", "medical_hospital_except_date", "medical_hospital_item", "medical_hospital_item_rel", "medical_hospital_user", "medical_hospital_virtual", "medical_info", "medical_item", "medical_item_cost", "medical_item_mutex", "medical_item_package", "medical_item_package_model", "medical_item_package_model_append", "medical_item_package_model_append_sub", "medical_item_package_model_sub", "medical_item_package_sub", "medical_item_syn", "medical_limit_float", "medical_limit_model", "medical_model_float", "medical_order_info", "medical_order_queue", "medical_package_check", "medical_paper_question", "medical_paper_question_item", "medical_plan", "medical_plan_user", "medical_precheck_paper", "medical_precheck_paper_questions", "medical_record_model", "medical_record_model_base", "medical_record_model_config", "medical_serious_result_item", "medical_stat_year", "medical_uni_item_class", "medical_uni_item_class_office", "medical_uni_item_class_sicks", "medical_uni_item_hospital", "medical_uni_item_info", "medical_uni_item_risk_rel", "medical_uni_item_unusual_rel", "medical_user_defend_cancer_result", "medical_user_diseases", "medical_user_diseases_item", "medical_user_exception", "medical_user_exception_item", "medical_user_form", "medical_user_form_sub", "medical_user_ill", "medical_user_ill_sub", "medical_user_image", "medical_user_image_item", "medical_user_limit", "medical_user_paper", "medical_user_paper_answer", "medical_user_result", "medical_user_result_ext", "medical_user_result_item", "medical_user_result_item_tmp_unmatch", "medical_user_sign", ] # ==================================================== def get_connection(): """建立 MySQL 数据库连接""" return pymysql.connect( host=DB_CONFIG["host"], port=DB_CONFIG["port"], user=DB_CONFIG["user"], password=DB_CONFIG["password"], database=DB_CONFIG["database"], charset=DB_CONFIG["charset"], ) def get_table_comment(cursor, table_name): """获取表的中文注释""" cursor.execute( """ SELECT TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s """, (DB_CONFIG["database"], table_name) ) row = cursor.fetchone() return row[0] if row else "" def get_columns_with_comments(cursor, table_name): """获取表的字段名和中文注释,按字段顺序排列""" cursor.execute( """ SELECT COLUMN_NAME, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s ORDER BY ORDINAL_POSITION """, (DB_CONFIG["database"], table_name) ) return cursor.fetchall() # [(column_name, comment), ...] def get_sample_rows(cursor, table_name, limit=3): """获取表的示例数据""" try: cursor.execute(f"SELECT * FROM `{table_name}` LIMIT %s", (limit,)) return cursor.fetchall() except Exception: return [] def make_header_style(): """生成表头样式""" fill = PatternFill(fill_type="solid", fgColor="4472C4") font = Font(bold=True, color="FFFFFF", size=11) alignment = Alignment(horizontal="center", vertical="center", wrap_text=True) thin = Side(style="thin", color="FFFFFF") border = Border(left=thin, right=thin, top=thin, bottom=thin) return fill, font, alignment, border def make_field_name_style(): """字段名列样式(浅蓝底)""" fill = PatternFill(fill_type="solid", fgColor="DCE6F1") font = Font(bold=True, size=10) alignment = Alignment(horizontal="left", vertical="center") return fill, font, alignment def make_table_title_style(): """表名标题行样式(深绿底白字)""" fill = PatternFill(fill_type="solid", fgColor="375623") font = Font(bold=True, color="FFFFFF", size=12) alignment = Alignment(horizontal="left", vertical="center") return fill, font, alignment def write_all_tables_to_sheet(ws, tables_data): """将所有表写入同一个 Sheet,每张表前有标题行""" header_fill, header_font, header_align, header_border = make_header_style() field_fill, field_font, field_align = make_field_name_style() title_fill, title_font, title_align = make_table_title_style() current_row = 1 for table_name, table_comment, columns, sample_rows in tables_data: # ---------- 第1行:表名 + 表注释(合并A-E列) ---------- title_text = f"{table_name} {table_comment or ''}" ws.merge_cells( start_row=current_row, start_column=1, end_row=current_row, end_column=5 ) title_cell = ws.cell(row=current_row, column=1, value=title_text) title_cell.fill = title_fill title_cell.font = title_font title_cell.alignment = title_align ws.row_dimensions[current_row].height = 22 current_row += 1 # ---------- 第2行:列头 ---------- headers = ["数据名", "中文注释", "示例数据1", "示例数据2", "示例数据3"] for col_idx, header in enumerate(headers, start=1): cell = ws.cell(row=current_row, column=col_idx, value=header) cell.fill = header_fill cell.font = header_font cell.alignment = header_align cell.border = header_border ws.row_dimensions[current_row].height = 18 current_row += 1 # ---------- 字段数据行 ---------- for field_index, (col_name, comment) in enumerate(columns): cell_a = ws.cell(row=current_row, column=1, value=col_name) cell_a.fill = field_fill cell_a.font = field_font cell_a.alignment = field_align ws.cell(row=current_row, column=2, value=comment or "") for sample_col, sample_row in enumerate(sample_rows, start=3): val = sample_row[field_index] if field_index < len(sample_row) else "" ws.cell(row=current_row, column=sample_col, value=str(val) if val is not None else "NULL") current_row += 1 # 表与表之间空一行 current_row += 1 # ---------- 统一设置列宽 ---------- ws.column_dimensions["A"].width = 28 ws.column_dimensions["B"].width = 32 ws.column_dimensions["C"].width = 30 ws.column_dimensions["D"].width = 30 ws.column_dimensions["E"].width = 30 def main(): print(f"正在连接 MySQL {DB_CONFIG['host']}:{DB_CONFIG['port']} ...") conn = get_connection() cursor = conn.cursor() print(f"共 {len(TARGET_TABLES)} 张表待处理") tables_data = [] for i, table_name in enumerate(TARGET_TABLES, start=1): print(f"[{i}/{len(TARGET_TABLES)}] 处理表: {table_name}") table_comment = get_table_comment(cursor, table_name) columns = get_columns_with_comments(cursor, table_name) if not columns: print(f" ⚠ 字段为空或表不存在: {table_name}") else: print(f" 字段数: {len(columns)}, 表注释: {table_comment or '(无)'}") sample_rows = get_sample_rows(cursor, table_name) tables_data.append((table_name, table_comment, columns, sample_rows)) cursor.close() conn.close() wb = openpyxl.Workbook() ws = wb.active ws.title = "表结构数据" write_all_tables_to_sheet(ws, tables_data) wb.save(OUTPUT_FILE) print(f"\n导出完成 -> {OUTPUT_FILE}") if __name__ == "__main__": main()