在数据分析和处理过程中,数据格式的多样性常常带来不同的技术挑战。例如,历史数据或日志数据可能存储在 .his
格式的文件中。为了便于分析和操作,我们通常需要将这些文件转为更常见的表格格式如 Excel 文件(.xlsx
)。在本文中,我们将介绍一个基于 Python 和 PyQt5 的 GUI 工具,展示如何实现 .his
文件到 Excel 的批量转换,并实现动态 UI 美化和多线程功能。
功能特点
- 支持单个文件或文件夹批量转换:用户可以选择单个
.his
文件或包含多个.his
文件的文件夹进行批量转换。 - 动态 UI 美化:使用随机颜色和渐变背景实现界面美化,增强用户体验。
- 进度条显示和日志更新:转换过程中,进度条实时更新,且日志输出转换结果和状态信息。
- 多线程支持:避免阻塞 UI 界面,提高程序响应速度。
pandas
用于处理表格数据和生成 Excel 文件,而 PyQt5
用于实现 GUI 界面。
核心代码解析
以下是项目的完整代码,并逐步讲解关键部分。
1. UI 美化类 UIStyler
首先,我们定义了一个用于美化界面的类 UIStyler
,通过随机颜色和渐变背景实现一个视觉吸引力的用户界面。
import randomclass UIStyler:def __init__(self, widget):self.widget = widgetself.apply_styles()def apply_styles(self):colors = ["#3498db", "#2ecc71", "#e74c3c", "#9b59b6", "#e67e22"]random_color = random.choice(colors)self.widget.setStyleSheet(f"""QWidget {{background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 {random_color}, stop:1 #ffffff);}}QLabel {{color: {random_color};font-size: 18px;font-weight: bold;}}QPushButton {{background-color: {random_color};color: white;border-radius: 8px;padding: 8px;}}QPushButton:hover {{background-color: #2980b9;}}QProgressBar {{border: 2px solid #dce4ec;border-radius: 5px;background: white;color: black;}}QProgressBar::chunk {{background-color: {random_color};width: 20px;}}QTextEdit {{border: 2px solid {random_color};background-color: #f0f8ff;color: black;}}""")
2. 数据转换类 ConverterThread
ConverterThread
使用 QThread
实现多线程操作,保证文件转换过程不会阻塞 UI 界面。通过 log_message
和 progress
信号,我们可以在 UI 中实时更新日志和进度条状态。
from PyQt5 import QtCore
import pandas as pdclass ConverterThread(QtCore.QThread):progress = QtCore.pyqtSignal(int)log_message = QtCore.pyqtSignal(str)def __init__(self, input_path, output_folder, is_single_file):super().__init__()self.input_path = input_pathself.output_folder = output_folderself.is_single_file = is_single_filedef run(self):if self.is_single_file:self.convert_single_his_to_excel(self.input_path)else:self.convert_folder_his_to_excel(self.input_path)def convert_single_his_to_excel(self, his_file):if not os.path.exists(self.output_folder):os.makedirs(self.output_folder)excel_file_path = os.path.join(self.output_folder, os.path.basename(his_file).replace('.his', '.xlsx'))try:with open(his_file, 'r', encoding='utf-8') as file:lines = file.readlines()header = lines[1].strip().split('\t')data = [line.strip().split('\t') for line in lines[2:]]df = pd.DataFrame(data, columns=header)df.to_excel(excel_file_path, index=False)self.log_message.emit(f"已转换: {his_file} -> {excel_file_path}")except Exception as e:self.log_message.emit(f"转换 {his_file} 失败: {e}")def convert_folder_his_to_excel(self, input_folder):files = [f for f in os.listdir(input_folder) if f.endswith('.his')]total_files = len(files)for i, filename in enumerate(files):his_file_path = os.path.join(input_folder, filename)self.convert_single_his_to_excel(his_file_path)progress_value = int((i + 1) / total_files * 100)self.progress.emit(progress_value)
3. 主界面类 HISConverterUI
HISConverterUI
是主界面类,包含文件选择、日志显示、进度条等界面元素。它负责与用户的交互。
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QVBoxLayout, QHBoxLayout, QLabel, QProgressBar, QTextEditclass HISConverterUI(QtWidgets.QWidget):def __init__(self):super().__init__()self.init_ui()def init_ui(self):self.setWindowTitle('HIS文件转Excel工具')self.setGeometry(100, 100, 500, 600)main_layout = QVBoxLayout()self.title_label = QLabel('HIS 文件转换工具', self)self.title_label.setAlignment(QtCore.Qt.AlignCenter)self.title_label.setStyleSheet("font-size: 18px; font-weight: bold; margin-bottom: 20px;")main_layout.addWidget(self.title_label)btn_layout = QHBoxLayout()self.select_file_btn = QtWidgets.QPushButton('选择单个文件')self.select_file_btn.clicked.connect(self.select_file)btn_layout.addWidget(self.select_file_btn)self.select_folder_btn = QtWidgets.QPushButton('选择文件夹')self.select_folder_btn.clicked.connect(self.select_folder)btn_layout.addWidget(self.select_folder_btn)main_layout.addLayout(btn_layout)self.progress_bar = QProgressBar(self)main_layout.addWidget(self.progress_bar)self.his_file_list = QTextEdit(self)self.his_file_list.setReadOnly(True)main_layout.addWidget(self.his_file_list)self.convert_btn = QtWidgets.QPushButton('开始转换')self.convert_btn.clicked.connect(self.start_conversion)main_layout.addWidget(self.convert_btn)self.add_footer_info(main_layout)self.setLayout(main_layout)self.ui_styler = UIStyler(self)self.input_path = ''self.output_folder = './output'self.is_single_file = Falseself.thread = Nonedef select_file(self):file_path, _ = QFileDialog.getOpenFileName(self, "选择一个.his文件", "", "HIS Files (*.his);;All Files (*)")if file_path:self.input_path = file_pathself.is_single_file = Trueself.his_file_list.clear()self.his_file_list.append(f"已选择文件: {file_path}")QMessageBox.information(self, "文件选择", f"已选择文件: {file_path}")def select_folder(self):folder_path = QFileDialog.getExistingDirectory(self, "选择文件夹")if folder_path:self.input_path = folder_pathself.is_single_file = Falseself.show_his_files_in_folder(folder_path)def start_conversion(self):if self.input_path:self.progress_bar.setValue(0)self.thread = ConverterThread(self.input_path, self.output_folder, self.is_single_file)self.thread.progress.connect(self.update_progress)self.thread.log_message.connect(self.append_log)self.thread.start()QMessageBox.information(self, "转换进行中", "文件转换已开始!")else:QMessageBox.warning(self, "警告", "请先选择文件或文件夹!")def update_progress(self, value):self.progress_bar.setValue(value)def append_log(self, message):self.his_file_list.append(message)def add_footer_info(self, layout):self.footer_label = QLabel(self)self.footer_label.setText("版权所有 © 2024 贵州安然智行科技有限责任公司\n联系方式: gzarzx@163.com | 电话: +085183865795")self.footer_label.setAlignment(QtCore.Qt.AlignCenter)self.footer_label.setStyleSheet("font-size: 12px; color: black; padding: 2px;")layout.addWidget(self.footer_label)
总结
本文提供了一个完整的 .his
文件批量转换为 Excel 工具,并通过动态美化、进度显示、多线程等技术提升了用户体验。希望该工具能为您的数据处理工作提供便利。