import sys
import pandas as pd
from 连接池到实验 import *
from PyQt5.QtWidgets import (
QApplication, QWidget, QLabel, QLineEdit, QPushButton,
QFileDialog, QMessageBox, QVBoxLayout, QComboBox, QHBoxLayout
)
import numpy as np
import os
import tempfile
import win32com.client as win32 # 用于操作Excel
# 主窗口类
class ExcelImporter(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Excel 导入 MySQL 工具")
self.resize(600, 400) # 增加窗口高度以容纳新控件
self.last_created_excel = None # 记录最后创建的Excel文件路径
self.templates = {
"客户信息": ["客户ID", "姓名"],
"产品信息": ["产品ID", "产品名称", "类别", "首拼", "库存量"],
"订单记录": ["订单号", "客户ID", "产品ID", "数量", "下单日期"]
}
self.init_ui()
def init_ui(self):
layout = QVBoxLayout()
# 模板选择区域
layout.addWidget(QLabel("选择模板:"))
template_layout = QHBoxLayout()
self.template_combo = QComboBox()
self.template_combo.addItems(self.templates.keys())
template_layout.addWidget(self.template_combo)
self.create_button = QPushButton("创建Excel")
self.create_button.clicked.connect(self.create_excel_template)
template_layout.addWidget(self.create_button)
self.complete_button = QPushButton("我已编辑完成")
self.complete_button.clicked.connect(self.on_complete_clicked)
self.complete_button.setEnabled(False) # 初始禁用
template_layout.addWidget(self.complete_button)
layout.addLayout(template_layout)
# 文件路径输入框
layout.addWidget(QLabel("选择 Excel 文件:"))
self.file_path_edit = QLineEdit()
self.browse_button = QPushButton("浏览")
self.browse_button.clicked.connect(self.select_file)
file_layout = QHBoxLayout()
file_layout.addWidget(self.file_path_edit)
file_layout.addWidget(self.browse_button)
layout.addLayout(file_layout)
# 表名输入框
layout.addWidget(QLabel("目标数据库表名:"))
self.table_name_edit = QLineEdit()
layout.addWidget(self.table_name_edit)
# 导入按钮
self.import_button = QPushButton("导入数据库")
self.import_button.clicked.connect(self.import_to_database)
layout.addWidget(self.import_button)
self.setLayout(layout)
def create_excel_template(self):
"""创建Excel模板并打开"""
try:
# 获取选中的模板名称
template_name = self.template_combo.currentText()
# 创建临时Excel文件
with tempfile.NamedTemporaryFile(suffix='.xlsx', delete=False) as tmp:
file_path = tmp.name
self.last_created_excel = file_path
# 创建DataFrame并写入列标题
headers = self.templates[template_name]
df = pd.DataFrame(columns=headers)
df.to_excel(self.last_created_excel, index=False)
# 使用Excel 2013打开文件
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = True
workbook = excel.Workbooks.Open(os.path.abspath(self.last_created_excel))
# 启用"我已编辑完成"按钮
self.complete_button.setEnabled(True)
QMessageBox.information(self, "成功", f"Excel模板已创建,请编辑后点击'我已编辑完成'")
except Exception as e:
QMessageBox.critical(self, "错误", f"创建Excel失败: {str(e)}")
def on_complete_clicked(self):
"""处理编辑完成按钮点击事件"""
if self.last_created_excel and os.path.exists(self.last_created_excel):
self.file_path_edit.setText(self.last_created_excel)
self.table_name_edit.setText(self.template_combo.currentText())
self.complete_button.setEnabled(False) # 重置按钮状态
else:
QMessageBox.warning(self, "警告", "未找到创建的Excel文件")
def select_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, "选择 Excel 文件", "", "Excel 文件 (*.xlsx *.xls)")
if file_path:
self.file_path_edit.setText(file_path)
def import_to_database(self):
file_path = self.file_path_edit.text()
table_name = self.table_name_edit.text()
if not file_path:
QMessageBox.critical(self, "错误", "请选择一个 Excel 文件")
return
if not table_name:
QMessageBox.critical(self, "错误", "请输入目标数据库表名")
return
try:
with POOL.connection() as conn:
with conn.cursor() as cursor:
df = pd.read_excel(file_path)
if df.empty:
QMessageBox.critical(self, "错误", "Excel 文件为空")
return
# 替换所有 NaN、inf、-inf 为 None
df.replace([np.nan, np.inf, -np.inf], None, inplace=True)
# 构建插入语句
if not table_name.isidentifier():
raise ValueError("表名包含非法字符")
columns = ', '.join(df.columns.tolist())
placeholders = ', '.join(['%s'] * len(df.columns))
insert_sql = f"INSERT INTO `{table_name}` ({columns}) VALUES ({placeholders})"
# 转换为元组列表
data = [tuple(row) for _, row in df.iterrows()]
# 批量插入
cursor.executemany(insert_sql, data)
conn.commit()
QMessageBox.information(self, "成功", f"{cursor.rowcount} 条记录已成功导入到表 '{table_name}'")
except Exception as e:
try:
conn.rollback()
except:
pass
QMessageBox.critical(self, "错误", f"导入失败: {str(e)}")
# 启动应用
if __name__ == "__main__":
app = QApplication(sys.argv)
window = ExcelImporter()
window.show()
sys.exit(app.exec_())
再加一个功能:1.创建一个按钮显示“完成首拼”,再新创建的excel文件里,会自动生成首拼,用python代码实现