from
PyQt5.QtNetwork
import
QLocalSocket, QLocalServer
from
PyQt5
import
QtCore
from
PyQt5.QtGui
import
QTextCursor, QColor
from
PyQt5.QtWidgets
import
*
import
sys,os
import
pandas as pd
from
PyQt5.QtWidgets
import
QApplication, QComboBox, QDialog, QVBoxLayout, QLabel, QPushButton,QFileDialog
from
win32com.client
import
Dispatch
import
openpyxl
class
ComboCheckBox(QComboBox):
def
__init__(
self
, items:
list
):
super
(ComboCheckBox,
self
).__init__()
self
.items
=
[
"全选"
]
+
items
self
.box_list
=
[]
self
.text
=
QLineEdit()
self
.state
=
0
q
=
QListWidget()
for
i
in
range
(
len
(
self
.items)):
self
.box_list.append(QCheckBox())
self
.box_list[i].setText(
self
.items[i])
item
=
QListWidgetItem(q)
q.setItemWidget(item,
self
.box_list[i])
if
i
=
=
0
:
self
.box_list[i].stateChanged.connect(
self
.all_selected)
else
:
self
.box_list[i].stateChanged.connect(
self
.show_selected)
q.setStyleSheet(
"font-size: 30px; font-weight: bold; height: 50px; margin-left: 15px"
)
self
.text.setReadOnly(
True
)
self
.setLineEdit(
self
.text)
self
.setModel(q.model())
self
.setView(q)
def
all_selected(
self
):
if
self
.state
=
=
0
:
self
.state
=
1
for
i
in
range
(
1
,
len
(
self
.items)):
self
.box_list[i].setChecked(
True
)
else
:
self
.state
=
0
for
i
in
range
(
1
,
len
(
self
.items)):
self
.box_list[i].setChecked(
False
)
self
.show_selected()
def
get_selected(
self
)
-
>
list
:
ret
=
[]
for
i
in
range
(
1
,
len
(
self
.items)):
if
self
.box_list[i].isChecked():
ret.append(
self
.box_list[i].text())
return
ret
def
show_selected(
self
):
self
.text.clear()
ret
=
'; '
.join(
self
.get_selected())
self
.text.setText(ret)
class
MyDialog(QDialog):
def
__init__(
self
):
col_list
=
list
(
map
(
chr
,
range
(
65
,
91
)))
self
.file_name
=
''
self
.output
=
'output.xlsx'
super
().__init__()
self
.textEdit
=
QTextEdit()
self
.pushExcel
=
QLabel(
"Excel表:"
)
self
.lineExcel
=
QLineEdit("")
self
.selExcel
=
QPushButton(
"请选择"
)
self
.pushGroup
=
QLabel(
"分组列: "
)
self
.listGroup
=
ComboCheckBox(col_list)
self
.pushMerge
=
QLabel(
"合并列: "
)
self
.listMerge
=
ComboCheckBox(col_list)
self
.pushGO
=
QPushButton(
"开始处理"
)
self
.pushSee
=
QPushButton(
"结果查询"
)
self
.hflo0
=
QFormLayout()
self
.hflo1
=
QFormLayout()
self
.hflo2
=
QFormLayout()
self
.hflo11
=
QFormLayout()
self
.hflo12
=
QFormLayout()
self
.hflo21
=
QFormLayout()
self
.hflo22
=
QFormLayout()
self
.hflo31
=
QFormLayout()
self
.hflo32
=
QFormLayout()
self
.hflo0.addRow(
self
.pushExcel)
self
.hflo1.addRow(
self
.lineExcel)
self
.hflo2.addRow(
self
.selExcel)
self
.hflo11.addRow(
self
.pushGroup)
self
.hflo12.addRow(
self
.listGroup)
self
.hflo21.addRow(
self
.pushMerge)
self
.hflo22.addRow(
self
.listMerge)
self
.hflo31.addRow(
self
.pushGO)
self
.hflo32.addRow(
self
.pushSee)
self
.vflo
=
QFormLayout()
self
.vflo.addRow(
self
.textEdit)
self
.hbox
=
QHBoxLayout()
self
.hbox.addLayout(
self
.hflo0)
self
.hbox.addLayout(
self
.hflo1)
self
.hbox.addLayout(
self
.hflo2)
self
.hbox.setSpacing(
0
)
self
.hbox2
=
QHBoxLayout()
self
.hbox2.addLayout(
self
.hflo11)
self
.hbox2.addLayout(
self
.hflo12)
self
.hbox2.setSpacing(
0
)
self
.hbox3
=
QHBoxLayout()
self
.hbox3.addLayout(
self
.hflo21)
self
.hbox3.addLayout(
self
.hflo22)
self
.hbox3.setSpacing(
0
)
self
.hbox4
=
QHBoxLayout()
self
.hbox4.addLayout(
self
.hflo31)
self
.hbox4.addLayout(
self
.hflo32)
self
.hbox4.setSpacing(
0
)
self
.vbox
=
QVBoxLayout()
self
.vbox.addLayout(
self
.vflo)
vlayout
=
QVBoxLayout()
vlayout.addLayout(
self
.hbox)
vlayout.addLayout(
self
.hbox2)
vlayout.addLayout(
self
.hbox3)
vlayout.addLayout(
self
.hbox4)
vlayout.addLayout(
self
.vbox)
self
.setLayout(vlayout)
self
.textEdit.setFontPointSize(
15
)
self
.textEdit.setReadOnly(
False
)
self
.textEdit.setTextBackgroundColor(QColor(
80
,
80
,
80
))
self
.textEdit.setTextColor(QColor(
200
,
220
,
180
))
self
.selExcel.clicked.connect(
self
.choose_file)
self
.pushGO.clicked.connect(
self
.load_file)
self
.pushSee.clicked.connect(
self
.load_See)
def
choose_file(
self
):
try
:
options
=
QFileDialog.Options()
options |
=
QFileDialog.DontUseNativeDialog
file_name, _
=
QFileDialog.getOpenFileName(
self
,
"选择文件"
, "
", "
Excel files (
*
.xlsx)", options
=
options)
if
file_name:
self
.lineExcel.setText(file_name)
self
.file_name
=
file_name
df
=
pd.read_excel(
self
.file_name)
list_df
=
list
(df)
list_dfmap
=
list
(
map
(
chr
,
range
(
65
,
65
+
len
(list_df))))
Clist
=
dict
(
zip
(list_dfmap, list_df))
print
(Clist)
self
.textEdit.setText(
'提示:从下面的对应关系上选择分组与合并列\n'
+
str
(Clist))
except
:
print
(
'文件选择出错'
)
def
load_file(
self
):
try
:
self
.close_excel_file(
self
.output)
print
(
'开始载入列名'
)
if
len
(
self
.file_name) <
=
0
:
print
(
'请选择需要处理的表格文件'
)
QMessageBox.information(
self
,
'提示'
,
"请选择需要处理的表格文件"
)
else
:
print
(
self
.file_name)
df
=
pd.read_excel(
self
.file_name).applymap(
str
)
list_df
=
list
(df)
list_dfmap
=
list
(
map
(
chr
,
range
(
65
,
65
+
len
(list_df))))
Clist
=
dict
(
zip
(list_dfmap, list_df))
print
(Clist)
see_Group
=
self
.listGroup.get_selected()
see_Merge
=
self
.listMerge.get_selected()
hb_name
=
list
(Clist.get(i)
for
i
in
see_Group)
hb_value
=
list
(Clist.get(i)
for
i
in
see_Merge)
print
(hb_name)
print
(hb_value)
list_c
=
list
(
set
(see_Group) &
set
(see_Merge))
print
(list_c)
if
len
(list_c) >
=
1
:
QMessageBox.information(
self
,
'提示'
,
"分组与合并列不能有重合{}"
.
format
(list_c))
else
:
print
(
'开始进行分组合并操作'
)
if
len
(see_Group) >
=
1
:
print
(
'分组列非空,执行下面代码'
)
if
len
(see_Merge) >
=
1
:
print
(
'合并列非空,执行分组合并任务'
)
value_y
=
{
'one'
:
lambda
x:
'、'
.join(
set
(x))}
print
(value_y)
value
=
dict
.fromkeys(hb_value, value_y.get(
'one'
))
result
=
df.groupby(hb_name).agg(value)
df1
=
df.drop_duplicates(subset
=
hb_name)
result
=
pd.merge(df1.drop(columns
=
hb_value).drop_duplicates(), result, on
=
hb_name)
result
=
result[list_df]
print
(result)
result.to_excel(
self
.output, index
=
False
)
QMessageBox.information(
self
,
'提示'
,
"以{}分组,以{}合并完成"
.
format
(hb_name,hb_value))
else
:
print
(
'合并列为空,单执行分组任务'
)
hb_Group
=
df.drop_duplicates(subset
=
hb_name)
print
(hb_Group)
hb_Group.to_excel(
self
.output, index
=
False
)
QMessageBox.information(
self
,
'提示'
,
"以{}分组完成"
.
format
(hb_name))
else
:
print
(
'分组列为空,请选择'
)
QMessageBox.information(
self
,
'提示'
,
"分组列为空,请选择"
)
except
:
print
(
'执行分组合并出错'
)
def
load_See(
self
):
try
:
print
(
"查询结果开始"
)
print
(
self
.output)
os.startfile(
self
.output)
except
:
print
(
'查询结果出错'
)
def
close_excel_file(
self
,closeexcel):
xlApp
=
Dispatch(
'Excel.Application'
)
xlApp.DisplayAlerts
=
False
workbooks_n
=
xlApp.Workbooks.Count
print
(f
'已打开工作簿的数量为:{workbooks_n}个'
)
if
workbooks_n <
0
:
return
for
i
in
range
(
1
, workbooks_n
+
1
):
path_
=
xlApp.Workbooks(i).Path
name_
=
xlApp.Workbooks(i).Name
path
=
path_
+
"\\backup_"
+
name_
if
(closeexcel
in
path):
xlApp.Workbooks(i).Close()
del
xlApp
if
__name__
=
=
"__main__"
:
try
:
app
=
QApplication(sys.argv)
serverName
=
'testEvaluatinoServer601'
socket
=
QLocalSocket()
socket.connectToServer(serverName)
if
socket.waitForConnected(
601
):
app.quit()
else
:
localServer
=
QLocalServer()
localServer.listen(serverName)
dialog
=
MyDialog()
dialog.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
dialog.show()
dialog.setWindowTitle(
'Excel分组合并 by.182294401'
)
sys.exit(app.exec_())
pass
except
:
pass