import
tkinter as tk
from
tkinter
import
filedialog, messagebox
import
threading
import
pandas as pd
import
os
import
sys
class
RedirectText:
def
__init__(
self
, text_widget):
self
.text_widget
=
text_widget
def
write(
self
, string):
self
.text_widget.insert(tk.END, string)
self
.text_widget.see(tk.END)
def
flush(
self
):
pass
def
find_key(directory, keyword, process_button, check_var, check_btn):
found_files
=
False
num
=
0
for
root, dirs, files
in
os.walk(directory):
for
filename
in
files:
if
check_var.get():
if
filename.endswith(
'.xls'
):
file_path
=
os.path.join(root, filename)
index_excel
=
find_key_in_excel(file_path, keyword,
'xls'
)
for
i
in
range
(
len
(index_excel)):
num
=
num
+
1
print
(f
"[{num}] "
+
file_path
+
f
": "
+
str
(index_excel[i]))
found_files
=
True
print
(
"******************************************\n"
)
if
filename.endswith(
'.xlsx'
):
file_path
=
os.path.join(root, filename)
index_excel
=
find_key_in_excel(file_path, keyword,
'xlsx'
)
for
i
in
range
(
len
(index_excel)):
num
=
num
+
1
print
(f
"[{num}] "
+
file_path
+
f
": "
+
str
(index_excel[i]))
found_files
=
True
print
(
"******************************************\n"
)
if
filename.endswith((
'.py'
,
'.txt'
,
'json'
,
'md'
,
'.c'
,
'.cpp'
,
'.h'
,
'.java'
,
'.js'
,
'.html'
,
'.css'
,
'.xml'
,
'.sql'
,
'.bat'
,
'.ps1'
,
'.sh'
,
'.yaml'
,
'.yml'
,
'.conf'
,
'.ini'
,
'.license'
)):
file_path
=
os.path.join(root, filename)
try
:
with
open
(file_path,
'r'
, encoding
=
'utf-8'
, errors
=
'ignore'
) as
file
:
content_lines
=
file
.readlines()
for
line_number, line
in
enumerate
(content_lines, start
=
1
):
if
keyword
in
line:
num
=
num
+
1
print
(f
"[{num}] "
+
file_path
+
f
": "
+
line.strip(), f
"({line_number})"
)
found_files
=
True
print
(
"******************************************\n"
)
except
IOError as e:
print
(f
"文件读取错误 {file_path}: {e}"
)
process_button.config(state
=
'normal'
)
check_btn.config(state
=
'normal'
)
if
not
found_files:
print
(f
"在'{directory}'下没有找到关键字为'{keyword}'的文件..."
)
process_button.config(state
=
'normal'
)
check_btn.config(state
=
'normal'
)
def
find_key_in_excel(file_path, key, typ):
try
:
if
typ
=
=
'xlsx'
:
sheets
=
pd.read_excel(file_path, sheet_name
=
None
, engine
=
'openpyxl'
,
header
=
None
)
else
:
sheets
=
pd.read_excel(file_path, sheet_name
=
None
, engine
=
'xlrd'
, header
=
None
)
except
Exception as e:
print
(f
"文件读取错误 {file_path}: {e}"
)
return
index_list
=
[]
try
:
for
sheet_name, sheet
in
sheets.items():
for
i
in
range
(sheet.shape[
0
]):
for
j
in
range
(sheet.shape[
1
]):
if
key
in
str
(sheet.iat[i, j]):
row_num
=
i
+
1
col_num
=
j
+
1
index_list.append([sheet_name, row_num, col_num])
return
index_list
except
IOError as e:
print
(f
"文件读取错误 {file_path}: {e}"
)
return
def
select_directory(entry_widget):
directory
=
filedialog.askdirectory()
if
directory:
entry_widget.delete(
0
, tk.END)
entry_widget.insert(
0
, directory)
def
show_info():
info_text
=
(
"Author: 灿\n"
"编译时间版本: 2024-08-12/ V-0.01\n"
"说明:读取指定目录下的文件,查找文件中包含的指定关键词,并输出到控制台。\n"
"支持文件类型:.py, .txt, json, md, .c, .cpp, .h, .java, .js, .html, .css, .xml, .sql, .bat, .ps1, .sh, .yaml, .yml, .conf, .ini, .license, .xls, .xlsx"
)
messagebox.showinfo(
"软件信息"
, info_text)
def
update_gui(button):
button.config(state
=
'normal'
)
def
start_task(process_button, path_entry, keyword_entry, check_var, check_btn):
process_button.config(state
=
'disabled'
)
check_btn.config(state
=
'disabled'
)
thread
=
threading.Thread(target
=
lambda
: find_key(path_entry.get(), keyword_entry.get(), process_button, check_var, check_btn))
thread.start()
def
create_gui():
root
=
tk.Tk()
root.title(
"文件查找工具"
)
root.geometry(
"600x500"
)
root.resizable(width
=
False
, height
=
False
)
label
=
tk.Label(root, text
=
"请选择文件夹路径:"
)
label.place(x
=
10
, y
=
10
, width
=
120
, height
=
30
)
path_entry
=
tk.Entry(root, width
=
40
)
path_entry.place(x
=
140
, y
=
10
, width
=
350
, height
=
30
)
browse_button
=
tk.Button(root, text
=
"浏览"
, command
=
lambda
: select_directory(path_entry))
browse_button.place(x
=
500
, y
=
10
, width
=
50
, height
=
30
)
label
=
tk.Label(root, text
=
"关键字:"
)
label.place(x
=
10
, y
=
50
, width
=
120
, height
=
30
)
keyword_entry
=
tk.Entry(root, width
=
40
)
keyword_entry.place(x
=
140
, y
=
50
, width
=
200
, height
=
30
)
check_var
=
tk.IntVar()
check_btn
=
tk.Checkbutton(root, text
=
"是否检索excel(勾选将会增加检索时间)"
, variable
=
check_var)
check_btn.place(x
=
350
, y
=
50
, width
=
240
, height
=
30
)
process_button
=
tk.Button(root, text
=
"开始查找"
,
command
=
lambda
: start_task(process_button, path_entry, keyword_entry, check_var, check_btn))
process_button.place(x
=
250
, y
=
90
, width
=
80
, height
=
30
)
info_button
=
tk.Button(root, text
=
"软件信息"
, command
=
show_info)
info_button.place(x
=
250
, y
=
130
, width
=
80
, height
=
30
)
console_frame
=
tk.Frame(root)
console_frame.place(x
=
10
, y
=
170
, width
=
580
, height
=
320
)
text_console
=
tk.Text(console_frame, wrap
=
'word'
, height
=
20
)
text_console.place(x
=
10
, y
=
0
, width
=
580
, height
=
320
)
redirect_text
=
RedirectText(text_console)
sys.stdout
=
redirect_text
root.mainloop()
if
__name__
=
=
'__main__'
:
create_gui()