【DBF格式转换器.exe】

news2024/11/15 8:02:12

一、概要

       DBF文件是一种数据库文件格式,通常用于存储表格数据。这种文件格式曾经被广泛使用,尤其是在一些较旧的数据库系统中。然而,随着时间的推移,其他更现代的文件格式,如XLS(Excel)、CSV、DOCX(Word文档)和TXT(文本文件)变得越来越流行。转换成这些现代文件格式的主要优势包括:

       1、兼容性:这些格式被更广泛的软件支持,包括Microsoft Office套件和其他许多现代的数据分析工具;(主要是用DBF的软件需要付费阅读)

       2、可读性:这些格式更容易被人类读取和理解。例如,CSV和TXT文件是纯文本文件,可以用任何文本编辑器打开。而XLS和DOCX文件则可以用Microsoft Office或类似的软件打开,这些软件提供了丰富的用户界面和数据分析工具;

       3、数据处理:转换成CSV或XLS格式可以使数据更容易被导入到数据分析工具或电子表格软件中,从而进行更高级的数据处理和分析;

       4、共享和发布:这些现代文件格式更适合于共享和发布数据。例如,如果你有一个数据集并希望其他人能够查看或分析,将其转换为CSV或XLS格式可能会更加方便。

       因此,将DBF文件转换为这些现代文件格式可以提高数据的可用性、可读性和可处理性。

二、使用说明

       1、在“DBF文件路径“中输入DBF文件路径;

       2、在“存储路径”中输入要存储的路径;

       3、选择要生成的文件格式,默认“EXCEL”;

       4、点击“运行”即可生成。

在这里插入图片描述

图1   软件操作界面

三、完整代码

       代码的整体架构比较清晰,阅读以下代码中的注释即理解。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2023-08-27 14:11
# @Author : Leuanghing Chen
# @Blog : https://blog.csdn.net/weixin_46153372?spm=1010.2135.3001.5421
# @File : DBF格式转换器.py
# @Software : PyCharm
# pyinstaller --exclude-module EXCLUDES --onefile -F -w --icon F:\python_demo\1、pyqt5_projects\25_读取dbf文件\format_conversion.ico F:\python_demo\1、pyqt5_projects\25_读取dbf文件\DBF格式转换器.py

import sys
import dbfread
import pandas as pd
from openpyxl import Workbook
from docx import Document                   # 导入docx包
from docx.shared import Pt, RGBColor, Cm    # 设置字体大小、颜色、页面边距
from docx.oxml.ns import qn                 # 中文字体
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT      # 导入单元格垂直对齐
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT           # 导入段落对齐
from PyQt5.QtCore import QSize, QTimer
from PyQt5.QtGui import QIcon, QPixmap, QFont
from PyQt5.QtWidgets import QFileDialog, QMainWindow, QDialog, QSizePolicy, QGridLayout, QTextEdit, QWidget, QLineEdit, QLabel, QToolButton
from PyQt5 import QtCore, QtGui, QtWidgets


# 使用说明对话框
class Instructions_Dialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle("使用说明")
        self.resize(420, 270)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)
        self.setMinimumSize(QSize(420, 270))
        self.setMaximumSize(QSize(420, 270))

        self.icon = QIcon()
        self.icon.addPixmap(QPixmap(r"F:\python_demo\1、pyqt5_projects\25_读取dbf文件\illustrate.ico"), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(self.icon)

        self.gridLayout = QGridLayout(self)
        self.textEdit = QTextEdit(self)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.textEdit.sizePolicy().hasHeightForWidth())
        self.textEdit.setSizePolicy(sizePolicy)
        self.textEdit.setMinimumSize(QSize(400, 250))
        self.textEdit.setMaximumSize(QSize(400, 250))
        self.textEdit.setFont(QFont("Times New Roman", 12))
        self.textEdit.setStyleSheet("font: 12pt \"Times New Roman\";")
        self.textEdit.insertHtml(
            "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
            "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
            "p, li { white-space: pre-wrap; }\n"
            "</style></head><body style=\" font-family:\'Times New Roman\'; font-size:12pt; font-weight:400; font-style:normal;\">\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\';\">1</span><span style=\" font-family:\'宋体\';\">、在“新</span><span style=\" font-family:\'SimSun\';\">BOM</span><span style=\" font-family:\'宋体\';\">路径“中输入新</span><span style=\" font-family:\'SimSun\';\">BOM</span><span style=\" font-family:\'宋体\';\">表所在的文件夹路径;</span><span style=\" font-family:\'SimSun\';\"> </span></p>\n"
            "<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\';\">2</span><span style=\" font-family:\'宋体\';\">、在“存储路径”中输入公司统一整理的</span><span style=\" font-family:\'SimSun\';\">BOM</span><span style=\" font-family:\'宋体\';\">文件夹,其中记录了新旧</span><span style=\" font-family:\'SimSun\';\">BOM</span><span style=\" font-family:\'宋体\';\">表;</span><span style=\" font-family:\'SimSun\';\"> </span></p>\n"
            "<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\';\">3</span><span style=\" font-family:\'宋体\';\">、点击“</span><span style=\" font-family:\'SimSun\';\">create</span><span style=\" font-family:\'宋体\';\">”即可将新</span><span style=\" font-family:\'SimSun\';\">BOM</span><span style=\" font-family:\'宋体\';\">表放入指定的文件夹:新</span><span style=\" font-family:\'SimSun\';\">BOM</span><span style=\" font-family:\'宋体\';\">表会移至“可编辑</span><span style=\" font-family:\'SimSun\';\">EXCEL</span><span style=\" font-family:\'宋体\';\">版本”和“最新版本”两个文件夹中,原在这两个文件夹的文件会移至“旧版本”文件夹,用于留档记录。</span><span style=\" font-family:\'SimSun\';\"> </span></p></body></html>")
        self.gridLayout.addWidget(self.textEdit, 0, 0, 1, 1)


# 版本对话框
class version_Dialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setObjectName("Dialog")

        self.icon = QtGui.QIcon()
        self.icon.addPixmap(
            QtGui.QPixmap(r"F:\python_demo\1、pyqt5_projects\25_读取dbf文件\version.ico"),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(self.icon)

        self.resize(420, 270)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)
        self.setMinimumSize(QtCore.QSize(420, 270))
        self.setMaximumSize(QtCore.QSize(420, 270))
        self.gridLayout = QtWidgets.QGridLayout(self)
        self.gridLayout.setObjectName("gridLayout")
        self.version_textEdit = QtWidgets.QTextEdit(self)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.version_textEdit.sizePolicy().hasHeightForWidth())
        self.version_textEdit.setSizePolicy(sizePolicy)
        self.version_textEdit.setMinimumSize(QtCore.QSize(400, 250))
        self.version_textEdit.setMaximumSize(QtCore.QSize(400, 250))
        font = QtGui.QFont()
        font.setFamily("Times New Roman")
        font.setPointSize(12)
        self.version_textEdit.setFont(font)
        self.version_textEdit.setStyleSheet("font: 12pt \"Times New Roman\";")
        self.version_textEdit.setObjectName("version_textEdit")
        self.version_textEdit.setReadOnly(True)         # 禁止编辑version_textEdit
        self.gridLayout.addWidget(self.version_textEdit)

        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("Dialog", "版本"))
        self.version_textEdit.setHtml(_translate("Dialog",
                                                 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
                                                 "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
                                                 "p, li { white-space: pre-wrap; }\n"
                                                 "</style></head><body style=\" font-family:\'Times New Roman\'; font-size:12pt; font-weight:400; font-style:normal;\">\n"
                                                 "<p align=\"justify\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\';\">Version:V1.0.20230902</span></p>\n"
                                                 "<p align=\"justify\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\';\">Author:Leuanghing Chen</span></p>\n"
                                                 "<p align=\"justify\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\';\">Blog:https://blog.csdn.net/weixin_46153372?spm=1010.2135.3001.5421</span></p></body></html>"))


# 主界面
class Ui_MainWindow(object):
    savepath_lineEdit: QLineEdit
    dbfpath_toolButton: QToolButton
    savepath_label: QLabel
    dbfpath_label: QLabel
    dbfpath_lineEdit: QLineEdit
    gridLayout: QGridLayout
    gridLayout_2: QGridLayout
    centralwidget: QWidget

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(750, 405)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        MainWindow.setFont(font)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("format_conversion.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.dbfpath_label = QtWidgets.QLabel(self.centralwidget)
        self.dbfpath_label.setMinimumSize(QtCore.QSize(150, 30))
        self.dbfpath_label.setMaximumSize(QtCore.QSize(150, 30))
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.dbfpath_label.setFont(font)
        self.dbfpath_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
        self.dbfpath_label.setObjectName("dbfpath_label")
        self.gridLayout.addWidget(self.dbfpath_label, 0, 0, 1, 1)
        self.dbfpath_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.dbfpath_lineEdit.sizePolicy().hasHeightForWidth())
        self.dbfpath_lineEdit.setSizePolicy(sizePolicy)
        self.dbfpath_lineEdit.setMinimumSize(QtCore.QSize(450, 30))
        self.dbfpath_lineEdit.setMaximumSize(QtCore.QSize(16777215, 30))
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(12)
        self.dbfpath_lineEdit.setFont(font)
        self.dbfpath_lineEdit.setObjectName("dbfpath_lineEdit")
        self.gridLayout.addWidget(self.dbfpath_lineEdit, 0, 1, 1, 6)
        self.dbfpath_toolButton = QtWidgets.QToolButton(self.centralwidget)
        self.dbfpath_toolButton.setMinimumSize(QtCore.QSize(60, 30))
        self.dbfpath_toolButton.setMaximumSize(QtCore.QSize(60, 30))
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.dbfpath_toolButton.setFont(font)
        self.dbfpath_toolButton.setObjectName("dbfpath_toolButton")
        self.gridLayout.addWidget(self.dbfpath_toolButton, 0, 7, 1, 1)
        self.savepath_label = QtWidgets.QLabel(self.centralwidget)
        self.savepath_label.setMinimumSize(QtCore.QSize(150, 30))
        self.savepath_label.setMaximumSize(QtCore.QSize(150, 30))
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.savepath_label.setFont(font)
        self.savepath_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
        self.savepath_label.setObjectName("savepath_label")
        self.gridLayout.addWidget(self.savepath_label, 1, 0, 1, 1)
        self.savepath_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.savepath_lineEdit.setMinimumSize(QtCore.QSize(450, 30))
        self.savepath_lineEdit.setMaximumSize(QtCore.QSize(16777215, 30))
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(12)
        self.savepath_lineEdit.setFont(font)
        self.savepath_lineEdit.setObjectName("savepath_lineEdit")
        self.gridLayout.addWidget(self.savepath_lineEdit, 1, 1, 1, 6)
        self.savepath_toolButton = QtWidgets.QToolButton(self.centralwidget)
        self.savepath_toolButton.setMinimumSize(QtCore.QSize(60, 30))
        self.savepath_toolButton.setMaximumSize(QtCore.QSize(60, 30))
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.savepath_toolButton.setFont(font)
        self.savepath_toolButton.setObjectName("savepath_toolButton")
        self.gridLayout.addWidget(self.savepath_toolButton, 1, 7, 1, 1)
        self.savepath_type_label = QtWidgets.QLabel(self.centralwidget)
        self.savepath_type_label.setMinimumSize(QtCore.QSize(150, 60))
        self.savepath_type_label.setMaximumSize(QtCore.QSize(150, 60))
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.savepath_type_label.setFont(font)
        self.savepath_type_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
        self.savepath_type_label.setObjectName("savepath_type_label")
        self.gridLayout.addWidget(self.savepath_type_label, 2, 0, 1, 1)
        self.excel_radioButton = QtWidgets.QRadioButton(self.centralwidget)
        self.excel_radioButton.setEnabled(True)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        font.setKerning(True)
        self.excel_radioButton.setFont(font)
        self.excel_radioButton.setMouseTracking(True)
        self.excel_radioButton.setTabletTracking(False)
        self.excel_radioButton.setChecked(True)
        self.excel_radioButton.setObjectName("excel_radioButton")
        self.gridLayout.addWidget(self.excel_radioButton, 2, 1, 1, 1)
        self.csv_radioButton = QtWidgets.QRadioButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.csv_radioButton.setFont(font)
        self.csv_radioButton.setObjectName("csv_radioButton")
        self.gridLayout.addWidget(self.csv_radioButton, 2, 2, 1, 1)
        self.word_radioButton = QtWidgets.QRadioButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.word_radioButton.setFont(font)
        self.word_radioButton.setObjectName("word_radioButton")
        self.gridLayout.addWidget(self.word_radioButton, 2, 3, 1, 1)
        self.txt_radioButton = QtWidgets.QRadioButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.txt_radioButton.setFont(font)
        self.txt_radioButton.setObjectName("txt_radioButton")
        self.gridLayout.addWidget(self.txt_radioButton, 2, 4, 1, 1)
        spacerItem = QtWidgets.QSpacerItem(78, 57, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem, 2, 5, 1, 1)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(120)
        sizePolicy.setVerticalStretch(60)
        sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
        self.pushButton.setSizePolicy(sizePolicy)
        self.pushButton.setMinimumSize(QtCore.QSize(120, 60))
        self.pushButton.setMaximumSize(QtCore.QSize(120, 60))
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(85, 170, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush)
        brush = QtGui.QBrush(QtGui.QColor(85, 170, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(85, 170, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(85, 170, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush)
        brush = QtGui.QBrush(QtGui.QColor(85, 170, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(85, 170, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(120, 120, 120))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(85, 170, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush)
        brush = QtGui.QBrush(QtGui.QColor(120, 120, 120))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush)
        brush = QtGui.QBrush(QtGui.QColor(85, 170, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(85, 170, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
        self.pushButton.setPalette(palette)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(20)
        self.pushButton.setFont(font)
        self.pushButton.setStyleSheet("background-color: rgb(85, 170, 255);\n"
                                      "")
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 2, 6, 1, 2)
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setEnabled(False)
        self.textEdit.setMinimumSize(QtCore.QSize(680, 200))
        self.textEdit.setStyleSheet("QTextEdit {  \n"
                                    "    background-color: rgb(199, 237, 204);   \n"
                                    "    selection-color: rgb(85, 255, 255);\n"
                                    "    font-family: \"楷体\";  \n"
                                    "    font-size: 14px; \n"
                                    "    }  \n"
                                    "QTextEdit::cursor {  \n"
                                    "    background-color: transparent;  \n"
                                    "    }  ")
        self.textEdit.setObjectName("textEdit")
        self.gridLayout.addWidget(self.textEdit, 3, 0, 1, 8)
        self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 750, 23))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        MainWindow.setMenuBar(self.menubar)
        self.illustration_action = QtWidgets.QAction(MainWindow)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(12)
        self.illustration_action.setFont(font)
        self.illustration_action.setObjectName("illustration_action")
        self.version_action = QtWidgets.QAction(MainWindow)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(12)
        self.version_action.setFont(font)
        self.version_action.setObjectName("version_action")
        self.menu.addAction(self.illustration_action)
        self.menu.addAction(self.version_action)
        self.menubar.addAction(self.menu.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        # 连接信号
        self.dbfpath_toolButton.clicked.connect(self.openFile)
        self.savepath_toolButton.clicked.connect(self.open_folder)
        self.pushButton.clicked.connect(self.format_conversion)

        # 连接对话框弹框
        self.illustration_action.triggered.connect(self.open_dialog)
        self.version_action.triggered.connect(self.open_version_dialog)

        self.textedit_initialization()

        # 创建一个定时器,每当文本改变时,都会在100毫秒后调用 self.scroll_to_bottom
        self.timer = QTimer()
        self.timer.timeout.connect(self.scroll_to_bottom)
        # 每当文本改变时,启动定时器
        self.textEdit.textChanged.connect(self.timer.start)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "DBF格式转换器"))
        self.dbfpath_label.setText(_translate("MainWindow", "DBF文件路径:"))
        self.dbfpath_toolButton.setText(_translate("MainWindow", "..."))
        self.savepath_label.setText(_translate("MainWindow", "保存路径:"))
        self.savepath_toolButton.setText(_translate("MainWindow", "..."))
        self.savepath_type_label.setText(_translate("MainWindow", "保存文件类型:"))
        self.excel_radioButton.setText(_translate("MainWindow", "EXCEL"))
        self.csv_radioButton.setText(_translate("MainWindow", "CSV"))
        self.word_radioButton.setText(_translate("MainWindow", "WORD"))
        self.txt_radioButton.setText(_translate("MainWindow", "TXT"))
        self.pushButton.setText(_translate("MainWindow", "运行"))
        self.menu.setTitle(_translate("MainWindow", "菜单"))
        self.illustration_action.setText(_translate("MainWindow", "说明"))
        self.version_action.setText(_translate("MainWindow", "版本"))

    # 确保光标在可见的范围内
    def scroll_to_bottom(self):
        self.textEdit.ensureCursorVisible()

    # 使用说明对话框
    def open_dialog(self):
        # 创建对话框实例
        dialog = Instructions_Dialog()
        # 显示对话框并等待用户响应
        dialog.exec_()

    # 版本对话框
    def open_version_dialog(self):
        # 创建对话框实例
        dialog = version_Dialog()
        # 显示对话框并等待用户响应
        dialog.exec_()

    # textEdit文本框信息初始化
    def textedit_initialization(self):
        self.textEdit.clear()
        self.textEdit.insertPlainText('Version:V1.0.20230826\n')
        self.textEdit.insertPlainText('Author:Leuanghing Chen\n')
        self.textEdit.insertPlainText('Blog:https://blog.csdn.net/weixin_46153372?spm=1010.2135.3001.5421\n')
        self.textEdit.insertPlainText('————————————————————————————————————————————————\n')
        self.textEdit.insertPlainText('The operation records are as follows:\n')

    # dbfpath_lineEdit打开文件
    def openFile(self):
        mainWindow = QMainWindow()
        file_path, _ = QFileDialog.getOpenFileName(mainWindow, 'Open file', './')
        if file_path:
            self.dbfpath_lineEdit.setText(file_path)
            self.textEdit.insertPlainText(self.dbfpath_label.text() + self.dbfpath_lineEdit.text() + "\n")

    # savepath_lineEdit打开文件夹
    def open_folder(self):
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.Directory)
        if file_dialog.exec_() == QFileDialog.Accepted:
            directory = file_dialog.directory().absolutePath()
            self.savepath_lineEdit.setText(directory)
            self.textEdit.insertPlainText(self.savepath_label.text() + self.savepath_lineEdit.text() + "\n")

    # 转换格式
    def format_conversion(self):
        if len(self.dbfpath_lineEdit.text()) != 0 and len(self.savepath_lineEdit.text()) != 0:
            encodings = ['gbk', 'ascii', 'big5', 'big5hk', 'cp037', 'cp273', 'cp424', 'cp437', 'cp500', 'cp720', 'cp737',
                         'cp775', 'cp850', 'cp852', 'cp855', 'cp856', 'cp857', 'cp858', 'cp860', 'cp861', 'cp862', 'cp863',
                         'cp864', 'cp865', 'cp866', 'cp869', 'cp874', 'cp1006', 'cp1250', 'cp1251', 'cp1252', 'cp1253',
                         'cp1254', 'cp1255', 'cp1256', 'cp1257', 'cp1258', 'euc_cn', 'euc_jis_2004', 'euc_jisx0213',
                         'euc_jp', 'euc_kr', 'gb18030', 'gb2312', 'hz', 'iso2022_jp', 'iso2022_jp_1', 'iso2022_jp_2',
                         'iso2022_jp_2ext', 'iso2022_jp_3', 'iso2022_jp_ext', 'iso2022_kr', 'iso8859_10', 'iso8859_13',
                         'iso8859_14', 'iso8859_15', 'iso8859_16', 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5',
                         'iso8859_6', 'iso8859_7', 'iso8']

            # 尝试使用不同的编码方式读取文件
            for encoding in encodings:
                try:
                    # 读取DBF文件并转换为DataFrame
                    with dbfread.DBF(self.dbfpath_lineEdit.text(), encoding=encoding) as table:
                        records = [record for record in table]
                        df = pd.DataFrame(records)
                    self.textEdit.insertPlainText("Reading file in “{}” encoding format.\n".format(encoding))

                    # 1、文件保存为excel
                    if self.excel_radioButton.isChecked():
                        wb = Workbook()  # 创建一个新的工作簿
                        ws = wb.active  # 选择活动工作表

                        # 写入数据
                        self.textEdit.insertPlainText("Writing data......\n")
                        # 写入表头
                        for i in range(len(df.columns.tolist()) + 1):
                            if i == 0:
                                ws.cell(row=1, column=1, value="序号")
                            else:
                                ws.cell(row=1, column=i + 1, value=df.columns.tolist()[i - 1])

                        # 写入数据
                        for row in range(len(df)):
                            for col in range(len(df.columns) + 1):
                                if col == 0:
                                    ws.cell(row=row + 2, column=col + 1, value=str(df.index.tolist()[row] + 1))
                                else:
                                    ws.cell(row=row + 2, column=col + 1, value=df.iloc[row, col - 1])

                        # 保存为Excel文件
                        wb.save(self.savepath_lineEdit.text() + "/{}.xlsx".format(self.dbfpath_lineEdit.text().split(r'/')[-1].split('.')[0]))
                        self.textEdit.insertPlainText("Excel file saved.\n")
                        break

                    # 2、文件保存为csv
                    elif self.csv_radioButton.isChecked():
                        # 写入数据
                        self.textEdit.insertPlainText("Writing data......\n")

                        # 在第一列插入新的列'序号'
                        new_column = pd.Series(list(map(lambda x: x + 1, df.index.tolist())))  # df.index.tolist()元素自加1
                        df.insert(0, '序号', new_column)

                        df.to_csv(self.savepath_lineEdit.text() + "/{}.csv".format(self.dbfpath_lineEdit.text().split(r'/')[-1].split('.')[0]), index=False, encoding='gbk')
                        self.textEdit.insertPlainText("CSV file saved.\n")
                        break

                    # 3、文件保存为word
                    elif self.word_radioButton.isChecked():
                        # 写入数据
                        self.textEdit.insertPlainText("Writing data......\n")

                        # 生成word文档
                        Doc = Document()

                        # 设置页面边距
                        sec = Doc.sections[0]  # sections对应文档中的“节”
                        sec.left_margin = Cm(1.5)  # 以下依次设置左、右、上、下页面边距
                        sec.right_margin = Cm(1.5)
                        sec.top_margin = Cm(1.5)
                        sec.bottom_margin = Cm(1.5)

                        # 创建表格
                        tab = Doc.add_table(len(df) + 1, len(df.columns) + 1, style="Table Grid")

                        # 列宽
                        tab.cell(0, 0).width = Cm(1.01)
                        tab.cell(0, 1).width = Cm(3.34)
                        tab.cell(0, 2).width = Cm(3.43)
                        tab.cell(0, 3).width = Cm(5.76)
                        tab.cell(0, 4).width = Cm(3.00)
                        tab.cell(0, 5).width = Cm(2.45)

                        # 将文字写入表格
                        # 写入表头
                        for i in range(len(df.columns.tolist()) + 1):
                            if i == 0:
                                tab.cell(0, i).text = "序号"
                            else:
                                tab.cell(0, i).text = df.columns.tolist()[i - 1]

                        # 写入内容
                        for row in range(len(df)):
                            for column in range(len(df.columns) + 1):
                                try:
                                    if column == 0:
                                        tab.cell(row + 1, 0).text = str(df.index.tolist()[row] + 1)
                                    else:
                                        tab.cell(row + 1, column).text = str(df.iloc[row, column - 1])

                                except AttributeError:
                                    self.textEdit.insertPlainText("AttributeError occurred, please contact the designer!!!\n")

                        # 将表格中所有单元格修改字体
                        for col in tab.rows:
                            # 单元格
                            for cell in col.cells:
                                # 单元格对齐方式为:中部居中对齐
                                cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                                cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

                                # 单元格的段落
                                for par in cell.paragraphs:
                                    # 设置行距
                                    par.paragraph_format.line_spacing = 1.0
                                    # 段前与段后间距
                                    par.paragraph_format.space_before = Pt(0)
                                    par.paragraph_format.space_after = Pt(0)

                                    for block in par.runs:
                                        # 字体样式操作:bold:加粗、italic:斜体、underline:带下划线、strike:删除线、double_strike:双删除线、shadow:阴影
                                        block.font.bold = False
                                        block.font.italic = False
                                        block.font.underline = False
                                        block.font.strike = False
                                        block.font.double_strike = False
                                        block.font.shadow = False
                                        # 初号=42磅 小初=36磅 一号=26磅 小一=24磅 二号=22磅 小二=18磅 三号=16磅 小三=15磅 四号=14磅
                                        # 小四=12磅 五号=10.5磅 小五=9磅 六号=7.5磅 小六=6.5磅 七号=5.5磅 八号=5磅
                                        block.font.size = Pt(12)
                                        block.font.color.rgb = RGBColor(0, 0, 0)  # rgb(0,0,0)为黑色
                                        block.font.name = '宋体'  # 英文字体设置
                                        block._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')  # 设置中文字体

                        # 第一行加粗
                        run = tab.cell(0, 0).paragraphs[0].runs[0]
                        run.font.bold = True  # 将文字块设置为粗体
                        run = tab.cell(0, 1).paragraphs[0].runs[0]
                        run.font.bold = True  # 将文字块设置为粗体
                        run = tab.cell(0, 2).paragraphs[0].runs[0]
                        run.font.bold = True  # 将文字块设置为粗体
                        run = tab.cell(0, 3).paragraphs[0].runs[0]
                        run.font.bold = True  # 将文字块设置为粗体
                        run = tab.cell(0, 4).paragraphs[0].runs[0]
                        run.font.bold = True  # 将文字块设置为粗体
                        run = tab.cell(0, 5).paragraphs[0].runs[0]
                        run.font.bold = True  # 将文字块设置为粗体

                        # 保存为Word文档
                        Doc.save(self.savepath_lineEdit.text() + "/{}.docx".format(self.dbfpath_lineEdit.text().split(r'/')[-1].split('.')[0]))
                        self.textEdit.insertPlainText("Word file saved.\n")
                        break

                    # 4、文件保存为txt
                    elif self.txt_radioButton.isChecked():
                        # 写入数据
                        self.textEdit.insertPlainText("Writing data......\n")

                        # 写入数据到txt文件
                        txt_filename = self.savepath_lineEdit.text() + "/{}.txt".format(self.dbfpath_lineEdit.text().split(r'/')[-1].split('.')[0])
                        with open(txt_filename, 'w') as file:
                            for row in range(len(df)):
                                if row == 0:
                                    for i in range(len(df.columns.tolist()) + 1):
                                        if i == 0:
                                            file.write(f"{'序号'}\t")  # 添加一个制表符
                                        else:
                                            file.write(f"{df.columns.tolist()[i - 1]}\t")  # 使用制表符(\t)分隔数据
                                    file.write("\n")  # 每行数据结束后添加换行符
                                else:
                                    file.write(f"{df.index.tolist()[row]}\t")
                                    for col in range(len(df.columns)):
                                        file.write(f"{df.iloc[row, col]}\t")  # 使用制表符(\t)分隔数据
                                    file.write("\n")  # 每行数据结束后添加换行符
                        self.textEdit.insertPlainText("TXT file saved.\n")
                        break

                    else:
                        self.textEdit.insertPlainText("Please select the file type to save.\n")

                except UnicodeDecodeError:
                    self.textEdit.insertPlainText("Failed to read file in “{}” encoding format.\n".format(encoding))

                except Exception as e:
                    # 处理未知错误
                    self.textEdit.insertPlainText("Error: {} occurred. Please contact the designer or try restarting the software!!!\n".format(str(e)))

        else:
            if len(self.dbfpath_lineEdit.text()) == 0:
                self.textEdit.insertPlainText(self.dbfpath_label.text().replace(":", "") + " is null.\n")

                if len(self.savepath_lineEdit.text()) == 0:
                    self.textEdit.insertPlainText(self.savepath_label.text().replace(":", "") + " is null.\n")


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)  # 创建一个QApplication对象
    MainWindow = QtWidgets.QMainWindow()  # 创建一个主窗口对象
    ui = Ui_MainWindow()  # 创建一个界面对象
    ui.setupUi(MainWindow)  # 设置主窗口的界面
    MainWindow.show()  # 显示主窗口
    sys.exit(app.exec_())  # 进入主事件循环,并监听窗口关闭事件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1431055.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入Spring MVC的工作流程

深入Spring MVC的工作流程 在Spring MVC的面试问题中&#xff0c;常常被询问到的一个问题。Spring MVC的程序中&#xff0c;HTTP请求是如何从开始到结束被处理的。为了研究这个问题&#xff0c;我们将需要深入学习一下Spring MVC框架的核心过程和工作流程。 1. 启动请求生命周…

代码随想录算法训练营29期|day39 任务以及具体任务

第九章 动态规划part02 62.不同路径 /*** 1. 确定dp数组下标含义 dp[i][j] 到每一个坐标可能的路径种类* 2. 递推公式 dp[i][j] dp[i-1][j] dp[i][j-1]* 3. 初始化 dp[i][0]1 dp[0][i]1 初始化横竖就可* 4. 遍历顺序 一行一行遍历* 5. 推导结果 。。。。。。。。** param m* p…

Windows内存管理 - 虚拟内存地址概念(Virtual Memory Address)

虽然可以寻址4GB的内存&#xff0c;而在PC里往往没有如此多的真实物理内存。操作系统和硬件&#xff08;这里指的是CPU中的内存管理单元MMU&#xff09;为使用者提供了虚拟内存的概念。Windows的所有程序&#xff08;包括Ring0层和Ring3层的程序&#xff09;可以操作的都是虚拟…

GPT3.5\GPT4系列计算完整prompt token数的官方方法

前言: ChatGPT如何计算token数&#xff1f;https://wtl4it.blog.csdn.net/article/details/135116493?spm1001.2014.3001.5502https://wtl4it.blog.csdn.net/article/details/135116493?spm1001.2014.3001.5502 GPT3.5\GPT4系列计算完整prompt token数的官方方法&#xff1…

航母编队反无人机蜂群作战能力需求分析

源自&#xff1a;指挥控制与仿真 作者&#xff1a;樊辉锦、巫银花、毕月、苏泽亚 “人工智能技术与咨询” 发布 声明:公众号转载的文章及图片出于非商业性的教育和科研目的供大家参考和探讨&#xff0c;并不意味着支持其观点或证实其内容的真实性。版权归原作者所有&#xff…

01 JDK的安装

JDK的安装 1 JDK的安装&#xff1a;参考&#xff1a; 1 JDK的安装&#xff1a; 说到Java&#xff0c;永远都有一个绕不开的话题&#xff0c;就是JDK(Java Development Kit)。JDK 是整个Java的核心&#xff0c;包括了Java运行环境&#xff0c;Java工具和Java基础的类库。安装JD…

来了来了,5000个红包封面免费领

今年公众号很慷慨&#xff0c;给长期运营的作者免费发放了6w个红包封面&#xff0c;感谢公众号平台。 往年还是自己花钱找别人设计&#xff0c;平台审核通过后才能正常发放给大家&#xff0c;自从AI绘画工具问世后&#xff0c;自己也能设计了。 下面的两个封面都是我用AI工具St…

05、全文检索 -- Solr -- Solr 全文检索之图形界面的文档管理(文档的添加、删除,如何通过关键字等参数查询文档)

目录 Solr 全文检索之文档管理添加文档使用 JSON 添加文档&#xff1a;使用 XML 添加文档: 删除文档使用 JSON 删除文档&#xff1a;使用 XML 删除文档&#xff1a; 查询文档查询文档的详细参数fq&#xff08;Filter Query&#xff09;&#xff1a;过滤sort&#xff1a;排序sta…

隧道穿透:常规反弹、加密反弹

目录 1、常规反弹 &#xff08;1&#xff09;Windows正向连接shell &#xff08;2&#xff09;Windows反向连接shell &#xff08;3&#xff09;Linux正向连接shell &#xff08;2&#xff09;利用Linux自带bash反弹Shell 2、加密反弹 1、常规反弹 假设在内网环境中发现…

寒假 day2

1、请编程实现单向循环链表的头插&#xff0c;头删、尾插、尾删 #include<stdio.h> #include<string.h> #include<stdlib.h> enum{FALSE-1,SUCCESS}; typedef int datatype; //定义节点结构体 //节点&#xff1a;数据域、指针域 typedef struct Node {//数…

机器学习系列——(九)决策树

简介 决策树作为机器学习的一种经典算法&#xff0c;在数据挖掘、分类和回归等任务中广泛应用。本文将详细介绍机器学习中的决策树算法&#xff0c;包括其原理、构建过程和应用场景。 原理 决策树是一种基于树状结构的监督学习算法&#xff0c;它通过构建一棵树来对数据进行分…

leetcode刷题(剑指offer)138.随机链表的复制

138.随机链表的复制 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原…

【Linux网络编程一】网络基础1(网络框架)

【Linux网络编程一】网络基础1&#xff08;网络框架&#xff09; 一.什么是协议1.通信问题2.协议本质3.网络协议标准 二.协议分层1.为什么协议要分层2.如何具体的分层 三.操作系统OS与网络协议栈的关系1.核心点&#xff1a;网络通信贯穿协议栈 四.局域网中通信的基本原理1.封装…

使用 IntelliJ IDEA 配合 Docker 对 Weblogic 中间件进行远程调试

使用idea对jar包远程调试&#xff1a; 打开一个springboot的项目进行远程调试设置&#xff1a; 运行&#xff1a; 其实我不太明白远程调试的意义&#xff0c;本地直接debug不好嘛。。。 点击debug的按钮&#xff0c;打断点测试&#xff1a; 跑到断点处&#xff1a; 远程de…

JDK17中的密封类sealed和permits使用指南:什么是Java中的sealed和permits?

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

MYSQL——MySQL8.3无法启动

在新电脑上装了个MySQL&#xff0c;但是无法使用net start mysql启动&#xff0c;很是纳闷&#xff0c;使用mysqld --console去查看报错&#xff0c;也是没报错的&#xff0c;但是奇怪的是&#xff0c;我输入完这个mysqld --console之后&#xff0c;就等于启动了mysql了&#x…

一步步成为React全栈大师:从环境搭建到应用部署

文章目录 第一步&#xff1a;环境搭建第二步&#xff1a;了解React基础第三步&#xff1a;组件与路由第四步&#xff1a;状态管理第五步&#xff1a;接口与数据交互第六步&#xff1a;样式与布局第七步&#xff1a;测试第八步&#xff1a;构建与部署《深入浅出React开发指南》内…

系统架构20 - 统一建模语言UML(上)

统一建模语言 组成要素事物关系 在目前的软件开发方法中&#xff0c;面向对象的方法占据着主导地位。面向对象方法的主导地位也决定着软件开发过程模型化技术的发展&#xff0c;面向对象的建模技术方法也就成为主导的方法。 公认的面向对象建模语言出现于20世纪70年代中期。从1…

快速上手AI代码生成:CodeGeeX

1. VSCode等IDE插件直接搜到 CodeGeeX 就可以安装&#xff0c;装上之后&#xff0c;会看到左侧出现了&#xff1a; 2. 登陆以后&#xff0c;在代码区域就可以直接用了。 3. 官网功能说明文档&#xff08;非常简洁清晰&#xff09;&#xff1a; https://zhipu-ai.feishu.cn/wik…

文心一言 VS 讯飞星火 VS chatgpt (193)-- 算法导论14.3 1题

一、用go语言&#xff0c;写出作用于区间树的结点且在 〇(1) 时间内更新 max 属性的过程 LEFT-ROTATE 的伪代码。 文心一言&#xff1a; 以下是一个简单的LEFT-ROTATE的伪代码&#xff0c;它对一个二叉搜索树进行左旋转操作。这个操作的作用是更新节点的max属性&#xff0c;使…