1 Star 1 Fork 0

justin / execl

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
v1.py 20.88 KB
一键复制 编辑 原始数据 按行查看 历史
nanorabbits 提交于 2023-12-05 11:19 . n/a
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
import ComboCheckBox
import datetime
import os
import subprocess
import sys
import time
import openpyxl as oy
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QDesktopWidget, \
QHBoxLayout, QVBoxLayout, QPushButton, QLineEdit, \
QTableWidget, QTableWidgetItem, QLabel, \
QMessageBox, \
QTreeWidget, QTreeWidgetItem
import pandas as pds
import numpy as np
class MainWindows(QWidget):
def __init__(self):
super().__init__()
self.address_line = None
self.fileListTb = None
self.table = None
self.lab = None
self.sourcePath = ''
self.destPath = ''
self.table_layout = None
self.selectFile = None
self.car_nums_input = None
# 窗体标题
self.setWindowTitle('数据计算')
# 窗体尺寸
self.resize(1200, 700)
self.setMinimumSize(600, 400)
self.setWindowIconText("数据计算")
# 窗体位置
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
# 创建顶部垂直方向布局 1
layout = QVBoxLayout()
layout.addLayout(self.init_header())
layout.addLayout(self.init_form())
# 创建表单垂直方向布局
layout.addLayout(self.init_table())
# 创建底部垂直方向布局
layout.addLayout(self.init_bottom())
self.setLayout(layout)
self.show()
def init_header(self):
# 创建顶部菜单布局 1
head_layout = QHBoxLayout()
# 添加按钮
self.address_line = address_line = QLineEdit()
address_line.setText('C:/Users/yukan/Desktop')
address_line.setFixedWidth(200)
address_line.setPlaceholderText("请输入文件所在的目录")
list_btn = QPushButton("获取文件列表")
list_btn.setFixedSize(100, 25)
list_btn.clicked.connect(self.event_add_click)
list_btn3 = QPushButton("车号车数列转行")
list_btn3.setFixedSize(100, 25)
list_btn3.clicked.connect(lambda: self.start_calc(1))
list_btn4 = QPushButton("结算表")
list_btn4.setFixedSize(100, 25)
list_btn4.clicked.connect(lambda: self.start_calc(2))
list_btn5 = QPushButton("加班天数")
list_btn5.setFixedSize(100, 25)
list_btn5.clicked.connect(lambda: self.start_calc(3))
self.car_nums_select = car_nums_select = ComboCheckBox.ComboCheckBox()
car_nums_select.setDisabled(True)
car_nums_select.setPlaceholderText("请输入车号")
car_nums_select.setFixedWidth(150)
car_nums_select.setFixedHeight(20)
desc_label = QLabel()
desc_label.setText('*****下面的表格仅显示每张表格的前20行数据做为预览*****')
head_layout.addWidget(address_line)
head_layout.addWidget(car_nums_select)
head_layout.addWidget(list_btn)
head_layout.addWidget(list_btn3)
head_layout.addWidget(list_btn4)
head_layout.addWidget(list_btn5)
head_layout.addWidget(desc_label)
head_layout.addStretch()
return head_layout
def init_form(self):
form_layout = QHBoxLayout()
form_layout.addStretch()
return form_layout
def init_table(self):
self.table_layout = table_layout = QHBoxLayout()
self.fileListTb = QTreeWidget()
self.fileListTb.setColumnCount(1)
self.fileListTb.setFixedWidth(200)
self.fileListTb.setHeaderLabels(['文件列表'])
self.fileListTb.clicked.connect(self.click_file_item)
self.table = tab = QTableWidget(0, 300)
table_layout.addWidget(self.fileListTb)
table_layout.addWidget(tab)
return table_layout
def init_bottom(self):
bottom_layout = QHBoxLayout()
self.lab = lab = QLabel()
lab.setText("休息中")
lab.setFixedWidth(200)
bottom_layout.addWidget(lab)
bottom_layout.addStretch()
return bottom_layout
def event_add_click(self):
try:
self.table_layout.removeWidget(self.fileListTb)
self.table_layout.removeWidget(self.table)
self.fileListTb = QTreeWidget()
self.fileListTb.setColumnCount(1)
self.fileListTb.setFixedWidth(200)
self.fileListTb.setHeaderLabels(['文件列表'])
self.fileListTb.clicked.connect(self.click_file_item)
self.table_layout.addWidget(self.fileListTb)
self.table_layout.addWidget(self.table)
self.fileListTb.expandAll()
self.sourcePath = self.address_line.text()
dirs = os.listdir(self.address_line.text())
for dir in dirs:
if dir.endswith('.xlsx'):
root = QTreeWidgetItem(self.fileListTb)
root.setText(0, dir)
root.setToolTip(0, dir)
except Exception as e:
QMessageBox.warning(self, '提示', str(e))
print(e)
def click_file_item(self):
try:
self.lab.setText('获取数据中...')
self.lab.repaint()
item = self.fileListTb.currentItem()
self.selectFile = item.text(0)
path = self.sourcePath + '\\' + item.text(0)
# 计算并显示表格数据
df = pds.read_excel(path, header=1, index_col=None, nrows=20, dtype=str)
dt = pds.read_excel(path, header=1, index_col=None, usecols=['车号'], dtype=str)
dt = dt['车号'].dropna().drop_duplicates().sort_values()
v = np.delete(dt.values, 0)
self.car_nums_select.loadItems(v.tolist())
self.car_nums_select.setDisabled(False)
self.table.clear()
for index, row in df.iterrows():
self.table.insertRow(index)
for i in range(len(df.columns)):
cell = QTableWidgetItem(str(row[i]))
if str(row[i]) == 'nan':
cell = QTableWidgetItem('')
cell.setFlags(Qt.ItemIsEnabled)
self.table.setItem(index, i, cell)
self.lab.setText('获取读取完成')
self.lab.repaint()
except FileNotFoundError as err:
QMessageBox.warning(self, '提示', str(err))
print(err)
except Exception as e:
QMessageBox.warning(self, '提示', str(e))
finally:
pass
def config_source(self):
from dialog import AlertDialog
dialog = AlertDialog(self)
dialog.setWindowModality(Qt.ApplicationModal)
dialog.exec_()
def start_calc(self, num):
try:
self.lab.setText('执行中...')
self.lab.repaint()
#
df = pds.read_excel(self.sourcePath + '/' + self.selectFile,
usecols=['司机姓名', '车号',
'发货时间', '车数',
'工程名称', '销售方量',
'施工部位',
'补方',
'退料', '公里数',
'超时,过磅,接水,退料',
'区间', '单据类型'],
header=1, dtype=str)
# 获取 选中的车号
car_nums = self.car_nums_select.Selectlist()
if len(car_nums) == 0:
if num == 1:
self.create_one_table(df)
# # 生成结算表汇总
if num == 2:
self.create_two_table(df)
# 生成加班人员汇总
if num == 3:
self.get_jia_ban_people_name(df)
else:
self.create_two_table(df[df['车号'].isin(car_nums)], '汇总')
time.sleep(3)
for num in car_nums:
time.sleep(3)
# 生成结算表汇总
self.create_two_table(df[df['车号'] == num], num)
subprocess.Popen(r'explorer /select, ' + self.sourcePath)
self.lab.setText('休息中...')
self.lab.repaint()
except (TypeError, PermissionError) as e:
QMessageBox.warning(self, '提示', '系统错误!')
self.write_logs(e)
except ValueError as e:
print(e)
QMessageBox.warning(self, '提示', '文件错误!')
def sum(self, nums, df):
return df[nums].at[3] + df[nums].at[4] + df[nums].at[5] + df[nums].at[6] + df[nums].at[7]
def multi(self, row1, row2, col, df):
return df[row1].at[col] * df[row2].at[col]
def task_start_callback(self, row_index):
cell_status = QTreeWidgetItem("2")
cell_status.setFlags(Qt.ItemIsEnabled)
self.table.setItem(row_index, 6, cell_status)
def write_logs(self, content):
with open('log.text', mode='a+') as f:
old = f.read()
f.seek(0)
f.writelines(str(content) + '\n')
f.writelines(old)
f.flush()
f.close()
def create_one_table(self, df):
start_time = time.time()
cell_name = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK',
'AL', 'AM', 'AN', 'AO', 'AP']
"""
计算结算表
:return: 无返回值
"""
"""
车号 司机姓名 车数(时间相差五分钟算一车,方量为0 的不计算)
生成第一种表格
:param df: df 对象
:return: 无返回值 直接输出 excel 文件
"""
dt = df[['司机姓名', '车号', '发货时间', '车数']]
dt = dt[~dt['车数'].isna()]
# 删除没有结算方量的数据
car_nums = dt['车号'].dropna().drop_duplicates()
keyValues = {}
length = len(car_nums.values)
current_nums = 0
for item in car_nums.values:
current_nums += 1
self.lab.setText('执行进度:' + str(current_nums) + '/' + str(length))
self.lab.repaint()
keyValues[item] = self.get_data_list(dt, item)
max_length = 0
for item in keyValues:
if max_length < len(keyValues[item]):
max_length = len(keyValues[item])
workbook = oy.load_workbook('./Blank.xlsx')
ws = workbook['Sheet1']
keyValues = sorted(keyValues.items(), key=lambda x: x[0])
nums = 1
for key in keyValues:
ws['A' + str(nums)] = key[0]
cou = 1
for i in key[1]:
if str(i) == 'nan' or i == 0:
continue
ws[cell_name[cou] + str(nums)] = i
cou = cou + 1
nums += 1
c_t = datetime.datetime.now().strftime('%Y-%m-%d%H%M%S')
workbook.save(self.sourcePath + '/' + c_t + "-行专列.xlsx")
workbook.close()
# wf = pds.DataFrame(keyValues, index=None)
# wf = wf.transpose()
# wf = wf.sort_index()
# c_t = datetime.datetime.now().strftime('%Y-%m-%d%H%M%S')
# wf.to_excel(self.sourcePath + '/' + c_t + 'ONE-' + self.selectFile, na_rep=0, float_format=float, index=False,
# header=None)
end_time = time.time()
QMessageBox.warning(self, '导出成功', "转换表导出成功,耗时%.2f" % (end_time - start_time) + "秒")
def sum_carNums(self, df, name):
n = df[df['司机姓名'] == name]
num = 0
time_list = []
for index, item in n.iterrows():
if str(item['车数']) != 'nan':
if self.has_sub_five_m(item['发货时间'], time_list):
time_list.append(item['发货时间'])
num += int(item['车数'])
return num
def has_sub_five_m(self, s, times):
format = '%Y-%m-%d %H:%M:%S'
if str(s) == 'nan':
return True
if len(times) == 0:
return True
for item in times:
it = datetime.datetime.strptime(item, format)
st = datetime.datetime.strptime(s, format)
sec = (it - st).total_seconds()
sec = abs(sec)
if sec / 60 < 5:
return False
return True
def get_data_list(self, df, car_nums):
t = df[df['车号'] == car_nums]
result = []
n = t['司机姓名'].drop_duplicates()
for item in n.values:
result.append(item)
result.append(self.sum_carNums(t, item))
return result
def create_two_table(self, df, car_nums=None):
workbook = oy.load_workbook('./结算表2.xlsx')
c = 'D'
try:
start_time = time.time()
s = ''
if car_nums is not None:
s = car_nums
workbook = oy.load_workbook('./单车结算表.xlsx')
c = 'E'
"""
生成第二张表 结算单
:return:
"""
self.lab.setText(s + '结算表开始计算...')
self.lab.repaint()
t = df['发货时间']
format = '%Y-%m-%d'
dt = datetime.datetime.strptime(t.values[0][0:7] + '-01', format)
last_day = pds.date_range(start=dt, periods=1, freq='M').day.tolist()[0]
dt2 = datetime.datetime.strptime(t.values[0][0:7] + '-' + str(last_day), format)
start_d = dt.strftime('%Y年%m月%d日')
last_d = dt2.strftime('%Y年%m月%d日')
self.lab.setText('结算:8')
self.lab.repaint()
# 计算方量
a1 = self.get_fang_liang_by_range(df, [0, 8])
a2 = self.get_fang_liang_by_range(df, [8, 15])
a3 = self.get_fang_liang_by_range(df, [15, 25])
a4 = self.get_fang_liang_by_range(df, [25, 26])
a5 = self.get_fang_liang_by_range(df, [26, 27])
a6 = self.get_fang_liang_by_range(df, [27, 28])
self.lab.setText('结算:7')
self.lab.repaint()
# 计算补方部分数据
ws = workbook['结算']
if car_nums is not None:
ws['A5'] = car_nums
# 所属期间:2023年7月01日-2023年7月31日
ws['A2'] = '所属期间:' + start_d + '-' + last_d
# 计算 普通运输范围
ws[c + '5'] = a1[0]
ws[c + '6'] = a2[0]
ws[c + '7'] = a3[0]
ws[c + '8'] = a4[0]
ws[c + '9'] = a5[0]
ws[c + '10'] = a6[0]
ws[c + '11'] = a1[2]
self.lab.setText('结算:6')
self.lab.repaint()
# 计算补方运输范围
ws[c + '14'] = a1[1]
ws[c + '15'] = a2[1]
ws[c + '16'] = a3[1]
ws[c + '17'] = a4[1]
ws[c + '18'] = a5[1]
ws[c + '19'] = a6[1]
ws[c + '20'] = a1[3]
self.lab.setText('结算:5')
self.lab.repaint()
if car_nums is None:
# 计算接水洗泵数据
jie_shui = self.get_jie_shui(df)
ws['D24'] = jie_shui
self.lab.setText('结算:4')
self.lab.repaint()
# 送水到工地
song_shui = self.get_song_shui(df)
ws['D25'] = song_shui
self.lab.setText('结算:3')
self.lab.repaint()
# 应收一拖多运费补贴 取区间那一列的数据
yun_fei = self.get_yunfei_butie(df)
ws['D28'] = yun_fei[0]
ws['D29'] = yun_fei[1]
ws['D30'] = yun_fei[2]
ws['D31'] = yun_fei[3]
self.lab.setText('结算:2')
self.lab.repaint()
# 应收超时费
chao_shi = self.get_chao_shi(df)
ws['D37'] = chao_shi[0]
ws['D38'] = chao_shi[1]
ws['D39'] = chao_shi[2]
ws['D42'] = chao_shi[3]
ws['D43'] = chao_shi[4]
ws['D44'] = chao_shi[5]
self.lab.setText('结算:1')
self.lab.repaint()
c_t = datetime.datetime.now().strftime('%Y-%m-%d%H%M%S')
workbook.save(self.sourcePath + '/' + s + '---' + c_t + "-结算表.xlsx")
workbook.close()
end_time = time.time()
QMessageBox.warning(self, '导出成功', s + "结算表导出成功,耗时%.2f" % (end_time - start_time) + "秒")
except Exception as e:
print(e)
QMessageBox.warning(self, '提示', '系统错误!')
def get_fang_liang_by_range(self, df, range):
# 第一个数据
a1 = 0
# 第二个数据 - 补方
a2 = 0
# 计算瓶改管
a3 = 0
# 瓶改管 补方
a4 = 0
for index, item in df.iterrows():
if str(item['工程名称']) != 'nan' and '瓶改' in item['工程名称']:
if str(item['销售方量']) != 'nan':
a3 += float(item['销售方量'])
if str(item['补方']) != 'nan':
a4 += float(item['补方'])
elif range[0] < float(item['公里数']) <= range[1]:
if str(item['销售方量']) != 'nan':
a1 += float(item['销售方量'])
if str(item['退料']) != 'nan':
a1 += float(item['退料'])
if str(item['补方']) != 'nan':
a2 += float(item['补方'])
return a1, a2, a3, a4
def get_jie_shui(self, df):
a = 0
for index, item in df.iterrows():
if '接水洗泵' in str(item['超时,过磅,接水,退料']):
if '四车' in item['超时,过磅,接水,退料'] or '4车' in item['超时,过磅,接水,退料']:
a += 4
if '三车' in item['超时,过磅,接水,退料'] or '3车' in item['超时,过磅,接水,退料']:
a += 3
elif '两车' in item['超时,过磅,接水,退料'] or '2车' in item['超时,过磅,接水,退料']:
a += 2
else:
a += 1
return a
def get_song_shui(self, df):
a = 0
for index, item in df.iterrows():
if '清水一车' in str(item['施工部位']):
a += 1
return a
def get_yunfei_butie(self, df):
a1 = 0
a2 = 0
a3 = 0
a4 = 0
for index, item in df.iterrows():
if '1-10' in str(item['区间']):
a1 += 1
elif '10-15' in str(item['区间']):
a2 += 1
elif '15-20' in str(item['区间']):
a3 += 1
elif '20-30' in str(item['区间']):
a4 += 1
return a1, a2, a3, a4
def get_chao_shi(self, df):
a1 = 0
a2 = 0
a3 = 0
a4 = 0
a5 = 0
a6 = 0
for index, item in df.iterrows():
if '合同单' in str(item['单据类型']) or '1' in str(item['单据类型']):
st = str(item['超时,过磅,接水,退料'])[0:4]
if 2.3 < float(st) <= 3.3:
a1 += 1
elif 3.3 < float(st) <= 4.3:
a2 += 1
elif 4.3 < float(st) <= 5.3:
a3 += 1
elif '现金单' in str(item['单据类型']) or '2' in str(item['单据类型']):
st = str(item['超时,过磅,接水,退料'])[0:4]
if 2.3 < float(st) <= 3.3:
a4 += 1
elif 3.3 < float(st) <= 4.3:
a5 += 1
elif 4.3 < float(st) <= 5.3:
a6 += 1
return a1, a2, a3, a4, a5, a6
def get_jia_ban_people_name(self, df):
a = []
dt = df[['司机姓名', '发货时间']].dropna()
for index, item in dt.iterrows():
# 判断发货时间是否在21:00-06:00
if item['发货时间'][11:19] >= '21:00:00':
if item['司机姓名'] != '':
item['发货时间'] = item['发货时间'][0:10]
a.append(item)
dt = pds.DataFrame(a).drop_duplicates().groupby('司机姓名')
b = []
for name, item in dt:
b.append([name, len(item)])
pds.DataFrame(b).to_excel(self.sourcePath + '/发货时间在2100-0600.xlsx', header=None, index=None)
# dt.to_excel(self.sourcePath + '/发货时间在2100-0600.xlsx', header=None, index='司机姓名')
if __name__ == '__main__':
ap = QApplication(sys.argv)
window = MainWindows()
window.show()
sys.exit(ap.exec_())
Python
1
https://gitee.com/yunwolf/execl.git
git@gitee.com:yunwolf/execl.git
yunwolf
execl
execl
master

搜索帮助