GUI拆分Excel
# -*- encoding: utf-8 -*-
"""
@Author:暗香彻骨.沐之杰 (Addis)
@Contact : qyx01@qq.com
@Time: 2022/3/8 14:02
@Software: PyCharm
@File: 文件处理v1.3.py
@Description: 可以将一个Excel工作簿中的多个工作表拆分成多个工作簿,按照指定字段
pip install pyinstaller, pyinstaller -F -w
"""
import os
import pathlib
import pandas as pd
from openpyxl import load_workbook
import ttkbootstrap as ttk
from tkinter.filedialog import askdirectory
from ttkbootstrap.constants import *
from ttkbootstrap.dialogs import MessageDialog
from ttkbootstrap.icons import Icon
from ttkbootstrap.scrolled import ScrolledText
from ttkbootstrap.tooltip import ToolTip
from tkinter.filedialog import askopenfilename
def show_dialog(msg, **kwargs):
md = MessageDialog(title="警告!", message=msg, buttons=["OK:primary"],
icon=Icon.error,
alert=True,
)
if "position" in kwargs:
position = kwargs.pop("position")
else:
position = None
md.show()
class FileHandling(ttk.Frame):
def __init__(self, master):
super().__init__(master, padding=15)
self.suffix_entry = None
self.fields_combox = None
self.sheets_combox = None
self.pack(fill=BOTH, expand=YES)
_path = pathlib.Path().absolute().as_posix()
self.path_var = ttk.StringVar(value=_path)
self.term_var = ttk.StringVar(value='md')
self.filename = ttk.StringVar()
# 目标文件
self.file_path = None
# 输出文件路径
self.out_path = None
self.sheets_data = []
self.fields_data = []
# header and labelframe option container
option_text = "操作区域"
self.option_lf = ttk.Labelframe(self, text=option_text, padding=15)
self.option_lf.pack(fill=X, expand=YES, anchor=N)
self.create_path_row()
self.create_file_row()
self.create_textbox()
self.create_combox_row()
self.create_suffix_row()
self.create_author_info()
def create_path_row(self):
"""添加该组件 to labelframe"""
path_row = ttk.Frame(self.option_lf)
path_row.pack(fill=X, expand=YES)
path_lbl = ttk.Label(path_row, text="路径:", width=8)
path_lbl.pack(side=LEFT, padx=(15, 0))
path_entry = ttk.Entry(path_row, bootstyle="info", textvariable=self.path_var)
path_entry.pack(side=LEFT, fill=X, expand=YES, padx=5)
browse_btn = ttk.Button(master=path_row, text="Path", command=self.on_path, bootstyle="info",
width=8)
browse_btn.pack(side=LEFT, padx=5)
ToolTip(path_entry, text="该路径用于保存拆分后的文件")
def create_file_row(self):
"""添加该组件 to labelframe"""
file_row = ttk.Frame(self.option_lf)
file_row.pack(fill=X, expand=YES, pady=15)
file_lbl = ttk.Label(file_row, text="文件:", width=8)
file_lbl.pack(side=LEFT, padx=(15, 0))
file_entry = ttk.Entry(file_row, bootstyle="info", textvariable=self.filename)
file_entry.pack(side=LEFT, fill=X, expand=YES, padx=5)
browse_btn = ttk.Button(master=file_row, text="File", command=self.open_file, bootstyle="info",
width=8)
browse_btn.pack(side=LEFT, padx=5)
def create_combox_row(self):
"""添加该组件 to labelframe"""
combox_row = ttk.Frame(self.option_lf)
combox_row.pack(fill=X, expand=YES, pady=15)
sheets_combox_lbl = ttk.Label(combox_row, text="工作表:", width=8)
sheets_combox_lbl.pack(side=LEFT, padx=(15, 0))
self.sheets_combox = ttk.Combobox(combox_row, values=self.sheets_data, state="readonly", bootstyle="info")
self.sheets_combox.pack(side=LEFT, padx=5)
self.sheets_combox.bind('<<ComboboxSelected>>', self.sheet_selected)
fields_combox_lbl = ttk.Label(combox_row, text="字段名:", width=8)
fields_combox_lbl.pack(side=LEFT, padx=(15, 0))
self.fields_combox = ttk.Combobox(combox_row, values=self.fields_data, state="readonly", bootstyle="info")
self.fields_combox.pack(side=LEFT, padx=5)
def create_suffix_row(self):
"""添加该组件 to labelframe"""
suffix_row = ttk.Frame(self.option_lf)
suffix_row.pack(fill=X, expand=YES, pady=15)
suffix_lbl = ttk.Label(suffix_row, text="后缀名:", width=8)
suffix_lbl.pack(side=LEFT, padx=(15, 0))
self.suffix_entry = ttk.Entry(suffix_row, bootstyle="info")
self.suffix_entry.pack(side=LEFT, fill=X, padx=5)
Start_but = ttk.Button(master=suffix_row, text="开始", command=self.on_start, bootstyle="primary", width=8)
Start_but.pack(side=RIGHT, fill=X, padx=5)
def create_textbox(self):
"""Create and add the widget elements"""
style = ttk.Style()
self.textbox = ScrolledText(
master=self,
highlightcolor=style.colors.primary,
highlightbackground=style.colors.border,
highlightthickness=1,
autohide=True
)
self.textbox.pack(fill=BOTH)
default_txt = "点击Path、File,然后开始拆分Excel文件吧!"
self.textbox.insert(END, default_txt + '\n')
def create_author_info(self):
author_info = ttk.Label(master=self, text="@Copyright 沐之杰.Addis Email:qyx01@qq.com")
author_info.pack(side=RIGHT, padx=(15, 0))
version_info = ttk.Label(master=self, text="Version:1.3")
version_info.pack(side=RIGHT, padx=(15, 15))
""" 方法区 """
def insert_log(self, log, *args):
self.textbox.insert(END, log + '\n')
def on_path(self):
"""输出文件路径 for directory browse"""
out_path = askdirectory(title="Browse directory")
if out_path:
self.path_var.set(out_path) # 文本框
self.out_path = out_path
def on_start(self):
file_path = self.file_path
out_path = self.out_path
filepath_is = os.path.exists(out_path)
if filepath_is:
if len(out_path) == 0:
show_dialog(msg="未选择目标路径!")
return
elif len(file_path) == 0:
show_dialog(msg="未选择目标文件!")
return
self.operate_excel()
else:
show_dialog(msg="目标路径错误!")
return
def open_file(self):
file_path = askopenfilename(title='选择Excel文件',
filetypes=[('Excel', '*.xlsx'), ('All Files', '*')])
if not file_path:
show_dialog("未选择文件!")
return
self.file_path = file_path
self.filename.set(file_path)
# 读取 excel文件中的sheetname
excel_data = pd.read_excel(file_path, None)
list_sheet = list(excel_data.keys())
# list_sheet = list(excel_data)
# print(list(excel_data))
# print(list_sheet)
self.sheets_name(list_sheet) # 方法
# 工作表名
def sheets_name(self, list_sheet):
self.sheets_data = list_sheet
self.sheets_combox["values"] = self.sheets_data
self.sheets_combox.current(0)
# 工作表名-选择
def sheet_selected(self, *args):
sheets_name = self.sheets_combox.get()
print(sheets_name)
df = pd.read_excel(self.file_path, sheet_name=sheets_name, dtype=str)
# field_name = list(df)
print(list(df))
self.fields_data = list(df)
self.fields_name(list(df))
# 字段名
def fields_name(self, field_name):
# field_name = self.field_name()
fields_data = field_name
self.fields_combox["values"] = fields_data
self.fields_combox.current(0)
# 字段名-选择
def field_selected(self, *args):
self.field_name = self.fields_combox.get()
log = "选择了字段:" + self.field_name
self.insert_log(log)
# --------------- 读取多个工作表 -----------------
def operate_excel(self, *args):
markname = str(self.suffix_entry.get())
out_path = self.out_path + '\\'
input_sheet_name = self.sheets_combox.get()
input_separation_fieldName = self.fields_combox.get()
print("文件:", self.file_path)
print("后缀名:", markname)
print("输出路径:", out_path)
print("工作表:", input_sheet_name)
print("字段名:", input_separation_fieldName)
# excel_data = pd.read_excel(self.file_path, None)
# list_sheet = list(excel_data.keys())
# print("工作表:", list_sheet)
# input_sheet_name = self.sheets_data
input_sheet_name = input_sheet_name.split(',')
circulation = 0
for only_sheet in input_sheet_name:
circulation += 1
print(only_sheet)
data = pd.read_excel(self.file_path, sheet_name=only_sheet, dtype=str)
rows = data.shape[0] # 获取行数 shape[1]获取列数
department_list = []
# print(data.columns)
# print(input_separation_fieldName)
print("总计 %s 行记录。" % rows)
for i in range(rows):
temp = data[input_separation_fieldName][i]
if temp not in department_list:
department_list.append(temp) # 分类存在一个列表中
# 写入Excel
if circulation == 1:
for department in department_list:
new_df = pd.DataFrame()
for i in range(0, rows):
if data[input_separation_fieldName][i] == department:
new_df = pd.concat([new_df, data.iloc[[i], :]], axis=0, ignore_index=True)
new_df.to_excel(out_path + str(department) + markname + ".xlsx",
sheet_name=only_sheet,
index=False) # 存成一个新excel
# writer_file = pd.ExcelWriter(file_path + '多工作表.xlsx') # 利用pd.ExcelWriter()存多张sheets
# print(circulation)
elif circulation >= 1:
for department in department_list:
output_excel = pd.ExcelWriter(out_path + str(department) + markname + ".xlsx")
book = load_workbook(output_excel)
new_df = pd.DataFrame()
for i in range(0, rows):
if data[input_separation_fieldName][i] == department:
new_df = pd.concat([new_df, data.iloc[[i], :]], axis=0, ignore_index=True)
# new_df.to_excel(output_excel, sheet_name=only_sheet,engine='openpyxl', index=False) # 注意加上index=FALSE 去掉index列
# output_excel.save()
with pd.ExcelWriter(self.output_excel, engine='openpyxl') as writer: # doctest: +SKIP
writer.book = book
new_df.to_excel(writer, sheet_name=only_sheet, index=False)
else:
print("\033[31;0m Error!")
print("End")
log = "成功:" + "总计 %s 行记录。" % rows
self.insert_log(log)
if __name__ == '__main__':
app = ttk.Window(title="文件处理", themename="litera")
FileHandling(app)
app.mainloop()
API请求
def get_url_batch(address, lng='', lat=''):
headers = {
'User-Agent': 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19',
"Content-Type": "application/json",
"AppKey": "915610589609328640"
}
# 互联网url
# url = ""
# 政务外网url
url = ""
# 需要的参数
params = {
"page": 1,
"limit": 10,
"address": address,
}
try:
r = requests.post(url, json=params, headers=headers)
# print(r.text)
res_json = json.loads(r.text)
res_data = res_json["data"]
# print(res_data)
# 打印序号,先用global关键字变成一个全局变量
global serialNumber
serialNumber += 1
time_now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
if len(res_data["rows"]) > 0:
print(serialNumber, res_data["rows"][0])
address = res_data["rows"][0]["address"]
lat = res_data["rows"][0]["lat"]
lng = res_data["rows"][0]["lng"]
res = [address, lng, lat, time_now]
# res_dict = {
# "province": res_data["rows"][0]["province"],
# "city": res_data["rows"][0]["city"],
# "town": res_data["rows"][0]["town"],
# "address": res_data["rows"][0]["address"],
# "lat": res_data["rows"][0]["lat"],
# "lng": res_data["rows"][0]["lng"]
# }
# print(res_dict)
return res
else:
print(serialNumber, res_data["rows"])
address = ""
lat = ""
lng = ""
res = [address, lng, lat, time_now]
return res
except Exception as e:
print(e)
address = address
lat = "异常"
lng = "异常"
res = [address, lng, lat, time_now]
return res
def read_excel_v2():
"""
返回多列更新到Excel
@return:
"""
df = pd.read_excel(r'../../../data_static/files/excel/地址获取经纬度.xlsx', sheet_name="结果")
# df["标准地址"] = df["地址"].apply(lambda x: get_url(x)) # 将返回结果直接保存在新的一列
df[["标准地址", "lng", "lat", "时间"]] = df.apply(lambda x: get_url_batch(x['地址']), axis=1, result_type='expand')
# df[['lng_', 'lat_']] = df.apply(lambda x: bd09_to_wgs84(x['lng'], x['lat']), axis=1, result_type='expand')
# 获取当前日期作为文件名的后缀
time_now = datetime.now().strftime('%Y-%m-%d')
out_file = r"../../../data_static/files/excel/地址获取经纬度 {_time}.xlsx".format(_time=time_now)
df.to_excel(out_file, sheet_name='结果', index=False)