【DBF格式转换器.exe】

一、概要

       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_())  # 进入主事件循环,并监听窗口关闭事件

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

红日靶场1搭建渗透

环境搭建 下载好镜像文件并解压&#xff0c;启动vmware 这里我用自己的win7 sp1虚拟机作为攻击机&#xff0c;设置为双网卡NAT&#xff0c;vm2 其中用ipconfig查看攻击机ip地址 设置win7 x64为双网卡&#xff0c;vm1&#xff0c;vm2 设置win08单网卡vm1&#xff0c;win2k3为单…

Leetcode—32. 最长有效括号【困难】(动态规划及ranges::max()使用)

2024每日刷题&#xff08;110&#xff09; Leetcode—32. 最长有效括号 栈实现代码 class Solution { public:int longestValidParentheses(string s) {stack<int> st;st.push(-1);int n s.size();int maxn 0;for(int i 0; i < n; i) {if(s[i] () {st.push(i);}…

《幻兽帕鲁》好玩吗?幻兽帕鲁能在Mac上运行吗?

最近一款叫做《幻兽帕鲁》的新游戏走红&#xff0c;成为了Steam游戏平台上&#xff0c;连续3周的销量冠军&#xff0c;有不少Mac电脑用户&#xff0c;利用Crossover成功玩上了《幻兽帕鲁》&#xff0c;其实Crossover已经支持很多3A游戏&#xff0c;包括《赛博朋克2077》《博德之…

XUbuntu22.04之两款实用画笔工具(二百一十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

开发智能化企业培训平台:教育系统源码的创新方法

在传统的企业培训模式中&#xff0c;往往面临着效率低下、内容过时以及难以个性化的问题。为了解决这些挑战&#xff0c;采用智能化技术成为了企业培训领域的热门趋势。通过开发智能化企业培训平台&#xff0c;可以提高培训效果、降低成本&#xff0c;并更好地满足员工多样化的…

【漏洞复现】MDVR数字视频录像机认证绕过漏洞

Nx01 产品简介 MDVR&#xff08;Mobile Digital Video Recorders&#xff09;硬盘录像机是一种使用先进的视音频编解码技术将车内外的视频进行数模转换&#xff0c;进行压缩存储的设备。 Nx02 漏洞描述 阿根廷研究员发现&#xff0c;通过使用“Cookie&#xff1a; uid admin”…

红队渗透靶机:TIKI: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、dirsearch 2、gobuster WEB web信息收集 searchsploit cms信息收集 ssh登录 提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:2…

基于Springboot开发的物品捎带系统[附源码]

基于Springboot开发的物品捎带系统[附源码] &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#x1f…

Transformer实战-系列教程3:Vision Transformer 源码解读1

&#x1f6a9;&#x1f6a9;&#x1f6a9;Transformer实战-系列教程总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 1、整体解读 在文本任务中大量使用了Transformer 架构&#xff0c;因为文本数据是一个序列非常好…

2、安全开发-Python-Socket编程端口探针域名爆破反弹Shell编码免杀

用途&#xff1a;个人学习笔记&#xff0c;欢迎指正&#xff01; 目录 主要内容&#xff1a; 一、端口扫描(未开防火墙情况) 1、Python关键代码: 2、完整代码&#xff1a;多线程配合Queue进行全端口扫描 二、子域名扫描 三、客户端&#xff0c;服务端Socket编程通信cmd命…

vue中使用html2canvas配合jspdf导出pdf(以及在导出时遇到的导出样式问题)

指定页面中导出为pdf格式并打包&#xff0c;使用html2canvas先转为图片格式&#xff0c;在利用jspdf转为pdf&#xff0c;最后下载打包为本地压缩包 yarn add html2canvas yarn add jspdf1. 注册一个插件并挂载 import html2Canvas from html2canvas import JsPDF from jspdf …

90.网游逆向分析与插件开发-游戏窗口化助手-项目需求与需求拆解

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;实现物品使用策略的功能-CSDN博客 项目需求&#xff1a; 在游戏窗口化时&#xff0c;可以在游戏之外弹出一个窗口&#xff0c;可以隐藏或者显示游戏窗口&#xff0c;显示游戏人物的基本状态&#xff…

天地伟业接入视频汇聚/云存储平台EasyCVR详细步骤

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

Quartus IP学习之ISSP(In-System Sources Probes)

一、ISSP IP概要&#xff1a; ISSP&#xff1a;In-System Sources & Probes Intel FPGA IP 作用&#xff1a; 分为In-System Sources与In-System Probesn-System Sources&#xff0c;输入端&#xff0c;等价于拨码开关&#xff0c;通过输入板载FPGA上的拨码开关状态改变…

Python基础知识:Python序列以及序列的索引、切片、相乘和相加

索引 索引就是序列中的每个元素所在的位置&#xff0c;可以通过从左往右的正数索引&#xff0c;也可以通过从右往左的负数索引。 从左往右的正数索引&#xff1a;在python序列中&#xff0c;第一个元素的索引值为0&#xff0c;第二个元素的索引值为1&#xff0c;以此类推&…

urllib2和cookielib的线程安全性

使用 urllib2 和 cookielib 发送 HTTP 请求和处理 cookies 的一些基本技巧。你可以根据具体需求进一步定制和扩展这些代码。注意&#xff0c;在 Python 3 中&#xff0c;urllib2 被拆分成 urllib.request 和 http.cookiejar 模块&#xff0c;但使用方式类似。下面就是我遇到的这…

Docker存储空间清理

不知不觉服务器存储空间被Docker掏空了… 查看Docker空间占用情况 使用docker system df命令&#xff0c;可以加 -v 查看详情 清理Docker不需要的内容 使用docker system prune -a命令清理Docker 所有停止的容器所有没有被使用的networks所有没容器的镜像所有build cache …

手工方式安装19.22RU

使用手工方式打RU19.22 参考文档&#xff1a; Supplemental Readme - Grid Infrastructure Release Update 12.2.0.1.x / 18c /19c (Doc ID 2246888.1) 操作步骤&#xff1a; 1 Stop the CRS managed resources running from DB homes. 2 Run the pre root script. 3 Patch G…

Korean Male Character- 19th Century

韩国男性角色- 19世纪资产包! 此包包含5个独特的角色模型和8个动画资源。 5个角色模型 1. 韩国男性_1 2. 韩国男选手_2 3. 韩国男_3 4. 韩国男式_框架 5. 韩国男选手_Ricksaw 共 8 个动画 :■ 站 ■ 步行 ■ 前俯 ■ 坐 ■ 木架_展台 ■ 独木桥_行走 ■ 框架_支架 ■…

Juc06_Lock8锁问题、字节码层面看Synchronized、反编译synchronized锁

1、Lock8 8锁问题 标准访问有 a、b 两个线程&#xff0c;请问先打印邮件还是短信sendEmail 方法暂停 3 秒钟&#xff0c;请问先打印邮件还是短信新增一个普通的 hello 方法&#xff0c;请问先打印邮件还是 hello有两部手机&#xff0c;请问先打印邮件还是短信两个静态同步方法…