Skip to content

Latest commit

 

History

26 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hello-world

Training on usage of repository

A new line is added to test commit

以下是实现所需功能的HTML和JavaScript代码:

<!DOCTYPE html>
<html>
<head>
    <title>数字跳转工具</title>
</head>
<body>
    <input type="text" id="numberInput" placeholder="请输入6-8位数字">
    <button onclick="handleRedirect()">立即跳转</button>

    <script>
        function handleRedirect() {
            // 获取用户输入内容
            const input = document.getElementById('numberInput').value.trim();
            
            // 验证输入格式
            if (!/^\d{6,8}$/.test(input)) {
                alert("请输入6-8位的纯数字");
                return;
            }

            // 转换为数字并验证数值范围
            const number = parseInt(input, 10);
            if (number < 100000 || number > 99999999) {
                alert("数字范围应为100000到99999999");
                return;
            }

            // 计算ID值
            const calculatedID = number - 50;
            
            // 验证计算结果
            if (calculatedID < 0) {
                alert("计算结果不能为负数");
                return;
            }

            // 构建并打开URL
            window.open(`https://abc.xyz/def.aspx?ID=${calculatedID}`, '_blank');
        }
    </script>

    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
        }
        input {
            padding: 8px;
            margin-right: 10px;
            width: 200px;
        }
        button {
            padding: 8px 16px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        button:hover {
            background-color: #45a049;
        }
    </style>
</body>
</html>

代码特点说明:

  1. 输入验证:

    • 使用正则表达式 /^\d{6,8}$/ 确保输入为6-8位纯数字
    • 数值范围验证(100000-99999999)
    • 计算结果非负验证
  2. 用户体验:

    • 清晰的错误提示
    • 输入框和按钮的基础样式
    • 按钮悬停效果
  3. 安全性:

    • 自动去除输入内容前后空格
    • 显式指定数字解析的十进制格式
    • 使用模板字符串构建URL防止注入

使用方法:

  1. 在输入框输入6-8位数字
  2. 点击按钮后:
    • 如果输入合法 → 新标签页打开目标URL
    • 如果输入不合法 → 显示对应错误提示

注意:实际使用时请将URL中的https://abc.xyz/def.aspx替换为真实的目标地址。

import os
import argparse
from openpyxl import load_workbook
import xlrd

def column_to_letter(col):
    """将列索引转换为Excel列字母(例如:0 -> A,26 -> AA)"""
    letter = ''
    while col >= 0:
        letter = chr(col % 26 + 65) + letter
        col = col // 26 - 1
    return letter

def process_xlsx(file_path, keywords):
    """处理.xlsx文件"""
    results = []
    try:
        wb = load_workbook(filename=file_path, read_only=True, data_only=True)
        for sheet_name in wb.sheetnames:
            ws = wb[sheet_name]
            for row in ws.iter_rows():
                for cell in row:
                    if cell.value is not None:
                        cell_value = str(cell.value)
                        matched_keywords = [k for k in keywords if k in cell_value]
                        for keyword in matched_keywords:
                            results.append({
                                'file': file_path,
                                'sheet': sheet_name,
                                'cell_address': cell.coordinate,
                                'keyword': keyword
                            })
        wb.close()
    except Exception as e:
        print(f"Error processing {file_path}: {str(e)}")
    return results

def process_xls(file_path, keywords):
    """处理.xls文件"""
    results = []
    try:
        wb = xlrd.open_workbook(file_path)
        for sheet in wb.sheets():
            sheet_name = sheet.name
            for row_idx in range(sheet.nrows):
                for col_idx in range(sheet.ncols):
                    cell = sheet.cell(row_idx, col_idx)
                    cell_value = str(cell.value)
                    matched_keywords = [k for k in keywords if k in cell_value]
                    for keyword in matched_keywords:
                        row_number = row_idx + 1
                        col_letter = column_to_letter(col_idx)
                        cell_address = f"{col_letter}{row_number}"
                        results.append({
                            'file': file_path,
                            'sheet': sheet_name,
                            'cell_address': cell_address,
                            'keyword': keyword
                        })
    except Exception as e:
        print(f"Error processing {file_path}: {str(e)}")
    return results

def search_excel_files(folder_path, keywords):
    """递归搜索文件夹中的Excel文件"""
    results = []
    for root, _, files in os.walk(folder_path):
        for file in files:
            file_path = os.path.join(root, file)
            if file.endswith('.xlsx'):
                results.extend(process_xlsx(file_path, keywords))
            elif file.endswith('.xls'):
                results.extend(process_xls(file_path, keywords))
    return results

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='在Excel文件中搜索关键词')
    parser.add_argument('folder', help='要搜索的文件夹路径')
    parser.add_argument('-k', '--keywords', nargs='+', required=True,
                        help='要搜索的关键词列表(用空格分隔)')
    args = parser.parse_args()

    search_results = search_excel_files(args.folder, args.keywords)

    for result in search_results:
        print(f"文件:{result['file']}")
        print(f"工作表:{result['sheet']}")
        print(f"单元格:{result['cell_address']}")
        print(f"关键词:{result['keyword']}\n{'='*50}")

再来

import os
import argparse
from openpyxl import load_workbook
import xlrd
from tqdm import tqdm

def column_to_letter(col):
    """将列索引转换为Excel列字母(例如:0 -> A,26 -> AA)"""
    letter = ''
    while col >= 0:
        letter = chr(col % 26 + 65) + letter
        col = col // 26 - 1
    return letter

def process_xlsx(file_path, keywords):
    """处理.xlsx文件"""
    results = []
    try:
        wb = load_workbook(filename=file_path, read_only=True, data_only=True)
        for sheet_name in wb.sheetnames:
            ws = wb[sheet_name]
            for row in ws.iter_rows():
                for cell in row:
                    if cell.value is not None:
                        cell_value = str(cell.value)
                        matched_keywords = [k for k in keywords if k in cell_value]
                        for keyword in matched_keywords:
                            results.append({
                                'file': file_path,
                                'sheet': sheet_name,
                                'cell_address': cell.coordinate,
                                'keyword': keyword
                            })
        wb.close()
    except Exception as e:
        print(f"\nError processing {file_path}: {str(e)}")
    return results

def process_xls(file_path, keywords):
    """处理.xls文件"""
    results = []
    try:
        wb = xlrd.open_workbook(file_path)
        for sheet in wb.sheets():
            sheet_name = sheet.name
            for row_idx in range(sheet.nrows):
                for col_idx in range(sheet.ncols):
                    cell = sheet.cell(row_idx, col_idx)
                    cell_value = str(cell.value)
                    matched_keywords = [k for k in keywords if k in cell_value]
                    for keyword in matched_keywords:
                        row_number = row_idx + 1
                        col_letter = column_to_letter(col_idx)
                        cell_address = f"{col_letter}{row_number}"
                        results.append({
                            'file': file_path,
                            'sheet': sheet_name,
                            'cell_address': cell_address,
                            'keyword': keyword
                        })
    except Exception as e:
        print(f"\nError processing {file_path}: {str(e)}")
    return results

def get_excel_files(folder_path):
    """获取所有Excel文件路径"""
    excel_files = []
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith(('.xlsx', '.xls')):
                excel_files.append(os.path.join(root, file))
    return excel_files

def search_excel_files_with_progress(folder_path, keywords):
    """带进度条的搜索函数"""
    print("正在扫描Excel文件...")
    file_list = get_excel_files(folder_path)
    total_files = len(file_list)
    
    results = []
    with tqdm(total=total_files, desc="搜索进度", unit="file", ncols=100) as pbar:
        for file_path in file_list:
            if file_path.endswith('.xlsx'):
                results.extend(process_xlsx(file_path, keywords))
            elif file_path.endswith('.xls'):
                results.extend(process_xls(file_path, keywords))
            pbar.update(1)
            pbar.set_postfix({"当前文件": os.path.basename(file_path)[:20]})
    return results

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='在Excel文件中搜索关键词')
    parser.add_argument('folder', help='要搜索的文件夹路径')
    parser.add_argument('-k', '--keywords', nargs='+', required=True,
                        help='要搜索的关键词列表(用空格分隔)')
    args = parser.parse_args()

    search_results = search_excel_files_with_progress(args.folder, args.keywords)

    print("\n搜索结果:")
    for result in search_results:
        print(f"文件:{result['file']}")
        print(f"工作表:{result['sheet']}")
        print(f"单元格:{result['cell_address']}")
        print(f"关键词:{result['keyword']}\n{'='*50}")

再来3

import os
import argparse
from tqdm import tqdm
from python_calamine import CalamineWorkbook

def search_excel_files(folder_path, keywords):
    """带进度条的搜索函数"""
    print("正在扫描Excel文件...")
    file_list = []
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.xlsx'):
                file_list.append(os.path.join(root, file))
    
    results = []
    total_files = len(file_list)
    
    with tqdm(total=total_files, desc="搜索进度", unit="file", ncols=100) as pbar:
        for file_path in file_list:
            try:
                # 使用calamine读取Excel文件
                wb = CalamineWorkbook.from_path(file_path)
                for sheet in wb.sheets:
                    df = sheet.to_python(skip_empty_rows=False)
                    for row_idx, row in enumerate(df, 1):
                        for col_idx, cell in enumerate(row, 1):
                            cell_value = str(cell) if cell is not None else ""
                            for keyword in keywords:
                                if keyword in cell_value:
                                    cell_address = f"{column_to_letter(col_idx-1)}{row_idx}"
                                    results.append({
                                        'file': file_path,
                                        'sheet': sheet.name,
                                        'cell_address': cell_address,
                                        'keyword': keyword
                                    })
            except Exception as e:
                print(f"\n错误处理文件 {file_path}: {str(e)}")
            finally:
                pbar.update(1)
                pbar.set_postfix({"当前文件": os.path.basename(file_path)[:20]})
    
    return results

def column_to_letter(col):
    """将列索引转换为Excel列字母(例如:0 -> A,26 -> AA)"""
    letter = ''
    while col >= 0:
        letter = chr(col % 26 + 65) + letter
        col = col // 26 - 1
    return letter or 'A'

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='在Excel文件中搜索关键词')
    parser.add_argument('folder', help='要搜索的文件夹路径')
    parser.add_argument('-k', '--keywords', nargs='+', required=True,
                       help='要搜索的关键词列表(用空格分隔)')
    args = parser.parse_args()

    search_results = search_excel_files(args.folder, args.keywords)

    print("\n搜索结果:")
    for result in search_results:
        print(f"文件:{result['file']}")
        print(f"工作表:{result['sheet']}")
        print(f"单元格:{result['cell_address']}")
        print(f"关键词:{result['keyword']}\n{'='*50}")

再4

import os
import argparse
import pandas as pd
from tqdm import tqdm

def convert_size_to_bytes(size_str):
    """将人类可读的文件大小转换为字节数"""
    units = {'B': 1, 'K': 1024, 'M': 1024**2, 'G': 1024**3}
    unit = size_str[-1].upper()
    if unit.isdigit():
        return int(size_str)
    value = float(size_str[:-1])
    return int(value * units[unit])

def column_to_letter(col):
    """将列索引转换为Excel列字母"""
    letter = ''
    while col >= 0:
        letter = chr(col % 26 + 65) + letter
        col = col // 26 - 1
    return letter or 'A'

def search_excel_files(folder_path, keywords, min_size=None, max_size=None):
    """带进度条和文件大小过滤的搜索函数"""
    print("正在扫描并筛选Excel文件...")
    file_list = []
    
    # 转换文件大小单位为字节
    min_bytes = convert_size_to_bytes(min_size) if min_size else 0
    max_bytes = convert_size_to_bytes(max_size) if max_size else float('inf')

    # 遍历文件并筛选
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.xlsx'):
                file_path = os.path.join(root, file)
                file_size = os.path.getsize(file_path)
                if min_bytes <= file_size <= max_bytes:
                    file_list.append(file_path)

    results = []
    total_files = len(file_list)
    
    with tqdm(total=total_files, desc="搜索进度", unit="file", ncols=100) as pbar:
        for file_path in file_list:
            try:
                # 使用Pandas读取Excel
                xls = pd.ExcelFile(file_path, engine='openpyxl')
                for sheet_name in xls.sheet_names:
                    df = xls.parse(sheet_name, header=None, dtype=str)
                    
                    # 遍历所有单元格
                    for row_idx, row in df.iterrows():
                        for col_idx, cell in enumerate(row):
                            cell_value = str(cell) if pd.notnull(cell) else ""
                            for keyword in keywords:
                                if keyword in cell_value:
                                    cell_address = f"{column_to_letter(col_idx)}{row_idx+1}"
                                    results.append({
                                        'file': file_path,
                                        'sheet': sheet_name,
                                        'cell_address': cell_address,
                                        'keyword': keyword
                                    })
                xls.close()
            except Exception as e:
                print(f"\n错误处理文件 {file_path}: {str(e)}")
            finally:
                pbar.update(1)
                pbar.set_postfix({"当前文件": os.path.basename(file_path)[:20]})
    
    return results

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='在Excel文件中搜索关键词')
    parser.add_argument('folder', help='要搜索的文件夹路径')
    parser.add_argument('-k', '--keywords', nargs='+', required=True,
                       help='要搜索的关键词列表(用空格分隔)')
    parser.add_argument('--min-size', help='最小文件大小(例如:1M, 500K)')
    parser.add_argument('--max-size', help='最大文件大小(例如:10M, 2G)')
    args = parser.parse_args()

    search_results = search_excel_files(
        args.folder, 
        args.keywords,
        min_size=args.min_size,
        max_size=args.max_size
    )

    print("\n搜索结果:")
    for result in search_results:
        print(f"文件:{result['file']}")
        print(f"工作表:{result['sheet']}")
        print(f"单元格:{result['cell_address']}")
        print(f"关键词:{result['keyword']}\n{'='*50}")

再5

import os
import argparse
import pandas as pd
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor
from python_calamine.pandad import pandas_monkeypatch

# 应用calamine补丁替换pandas的Excel引擎
pandas_monkeypatch()

def convert_size_to_bytes(size_str):
    """将人类可读的文件大小转换为字节数"""
    units = {'B': 1, 'K': 1024, 'M': 1024**2, 'G': 1024**3}
    if not size_str: return 0
    
    unit = size_str[-1].upper()
    if unit.isdigit():
        return int(size_str)
    value = float(size_str[:-1])
    return int(value * units.get(unit, 1))

def column_to_letter(col):
    """将列索引转换为Excel列字母"""
    letter = ''
    while col >= 0:
        letter = chr(col % 26 + 65) + letter
        col = col // 26 - 1
    return letter or 'A'

def process_single_file(file_path, keywords):
    """处理单个文件并返回结果"""
    results = []
    try:
        with pd.ExcelFile(file_path, engine="calamine") as xls:
            for sheet_name in xls.sheet_names:
                df = xls.parse(
                    sheet_name,
                    header=None,
                    dtype=str,
                    na_filter=False,
                    engine="calamine"
                )
                
                # 遍历所有单元格
                for row_idx, row in df.iterrows():
                    for col_idx, cell in enumerate(row):
                        if pd.isna(cell):
                            continue
                        cell_value = str(cell)
                        for keyword in keywords:
                            if keyword in cell_value:
                                cell_address = f"{column_to_letter(col_idx)}{row_idx+1}"
                                results.append({
                                    'file': file_path,
                                    'sheet': sheet_name,
                                    'cell_address': cell_address,
                                    'keyword': keyword
                                })
    except Exception as e:
        print(f"\n错误处理文件 {file_path}: {str(e)}")
    return results

def search_excel_files(folder_path, keywords, min_size=None, max_size=None, workers=4):
    """多线程搜索函数"""
    print("正在扫描并筛选Excel文件...")
    file_list = []
    
    # 转换文件大小单位
    min_bytes = convert_size_to_bytes(min_size) if min_size else 0
    max_bytes = convert_size_to_bytes(max_size) if max_size else float('inf')

    # 遍历文件并筛选
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.xlsx'):
                file_path = os.path.join(root, file)
                file_size = os.path.getsize(file_path)
                if min_bytes <= file_size <= max_bytes:
                    file_list.append(file_path)

    total_files = len(file_list)
    results = []
    
    with ThreadPoolExecutor(max_workers=workers) as executor:
        # 创建进度条
        with tqdm(total=total_files, desc="搜索进度", unit="file", ncols=100) as pbar:
            # 提交任务
            futures = []
            for file_path in file_list:
                future = executor.submit(process_single_file, file_path, keywords)
                future.add_done_callback(lambda _: pbar.update(1))
                futures.append(future)
            
            # 收集结果
            for future in futures:
                results.extend(future.result())
                pbar.set_postfix({"当前进度": f"{pbar.n}/{pbar.total}"})

    return results

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='多线程Excel文件搜索工具')
    parser.add_argument('folder', help='要搜索的文件夹路径')
    parser.add_argument('-k', '--keywords', nargs='+', required=True,
                       help='要搜索的关键词列表(用空格分隔)')
    parser.add_argument('--min-size', help='最小文件大小(例如:1M, 500K)')
    parser.add_argument('--max-size', help='最大文件大小(例如:10M, 2G)')
    parser.add_argument('-w', '--workers', type=int, default=4,
                       help='线程池工作线程数(默认:4)')
    args = parser.parse_args()

    search_results = search_excel_files(
        args.folder, 
        args.keywords,
        min_size=args.min_size,
        max_size=args.max_size,
        workers=args.workers
    )

    print("\n搜索结果:")
    for result in search_results:
        print(f"文件:{result['file']}")
        print(f"工作表:{result['sheet']}")
        print(f"单元格:{result['cell_address']}")
        print(f"关键词:{result['keyword']}\n{'='*50}")

再6

import os
import argparse
import pandas as pd
import threading
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor
from python_calamine.pandad import pandas_monkeypatch

# 应用calamine补丁替换pandas的Excel引擎
pandas_monkeypatch()

# 全局锁用于保证文件写入安全
result_lock = threading.Lock()
status_lock = threading.Lock()

class SearchManager:
    def __init__(self, folder, result_file="search_results.log", status_file="search_status.txt"):
        self.folder = folder
        self.result_file = os.path.join(folder, result_file)
        self.status_file = os.path.join(folder, status_file)
        
        # 初始化已完成文件记录
        self.completed_files = set()
        if os.path.exists(self.status_file):
            with open(self.status_file, 'r') as f:
                self.completed_files = set(f.read().splitlines())
        
        # 初始化结果文件(追加模式)
        if not os.path.exists(self.result_file):
            with open(self.result_file, 'w') as f:
                f.write("文件路径,工作表名,单元格地址,关键词\n")

    def record_result(self, result):
        """线程安全地记录结果"""
        with result_lock:
            # 实时显示结果
            print(f"[实时发现] {result['file']} -> {result['sheet']}!{result['cell_address']} ({result['keyword']})")
            
            # 保存到结果文件
            with open(self.result_file, 'a') as f:
                f.write(f"{result['file']},{result['sheet']},{result['cell_address']},{result['keyword']}\n")

    def mark_completed(self, file_path):
        """标记文件已完成处理"""
        with status_lock:
            with open(self.status_file, 'a') as f:
                f.write(f"{file_path}\n")
            self.completed_files.add(file_path)

def convert_size_to_bytes(size_str):
    """将人类可读的文件大小转换为字节数"""
    units = {'B': 1, 'K': 1024, 'M': 1024**2, 'G': 1024**3}
    if not size_str: return 0
    
    unit = size_str[-1].upper()
    if unit.isdigit():
        return int(size_str)
    value = float(size_str[:-1])
    return int(value * units.get(unit, 1))

def column_to_letter(col):
    """将列索引转换为Excel列字母"""
    letter = ''
    while col >= 0:
        letter = chr(col % 26 + 65) + letter
        col = col // 26 - 1
    return letter or 'A'

def process_single_file(file_path, keywords, manager):
    """处理单个文件并返回结果"""
    results = []
    try:
        with pd.ExcelFile(file_path, engine="calamine") as xls:
            for sheet_name in xls.sheet_names:
                df = xls.parse(
                    sheet_name,
                    header=None,
                    dtype=str,
                    na_filter=False,
                    engine="calamine"
                )
                
                # 遍历所有单元格
                for row_idx, row in df.iterrows():
                    for col_idx, cell in enumerate(row):
                        if pd.isna(cell):
                            continue
                        cell_value = str(cell)
                        for keyword in keywords:
                            if keyword in cell_value:
                                cell_address = f"{column_to_letter(col_idx)}{row_idx+1}"
                                result = {
                                    'file': file_path,
                                    'sheet': sheet_name,
                                    'cell_address': cell_address,
                                    'keyword': keyword
                                }
                                results.append(result)
                                manager.record_result(result)
        # 标记文件完成处理
        manager.mark_completed(file_path)
    except Exception as e:
        print(f"\n错误处理文件 {file_path}: {str(e)}")
    return results

def search_excel_files(folder_path, keywords, min_size=None, max_size=None, workers=4):
    """支持断点续查的多线程搜索函数"""
    manager = SearchManager(folder_path)
    
    print("正在扫描并筛选Excel文件...")
    file_list = []
    
    # 转换文件大小单位
    min_bytes = convert_size_to_bytes(min_size) if min_size else 0
    max_bytes = convert_size_to_bytes(max_size) if max_size else float('inf')

    # 遍历文件并筛选
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.xlsx'):
                file_path = os.path.join(root, file)
                # 跳过已处理文件
                if file_path in manager.completed_files:
                    continue
                file_size = os.path.getsize(file_path)
                if min_bytes <= file_size <= max_bytes:
                    file_list.append(file_path)

    total_files = len(file_list)
    results = []
    
    with ThreadPoolExecutor(max_workers=workers) as executor:
        # 创建进度条
        with tqdm(total=total_files, desc="搜索进度", unit="file", ncols=100) as pbar:
            # 提交任务
            futures = []
            for file_path in file_list:
                future = executor.submit(process_single_file, file_path, keywords, manager)
                future.add_done_callback(lambda _: pbar.update(1))
                futures.append(future)
            
            # 收集结果
            for future in futures:
                try:
                    results.extend(future.result())
                except Exception as e:
                    print(f"\n任务执行错误: {str(e)}")
                pbar.set_postfix({"剩余文件": f"{total_files - pbar.n}"})

    # 完成后清理状态文件(如需保留注释此行)
    # os.remove(manager.status_file)
    return results

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='支持断点续查的多线程Excel搜索工具')
    parser.add_argument('folder', help='要搜索的文件夹路径')
    parser.add_argument('-k', '--keywords', nargs='+', required=True,
                       help='要搜索的关键词列表(用空格分隔)')
    parser.add_argument('--min-size', help='最小文件大小(例如:1M, 500K)')
    parser.add_argument('--max-size', help='最大文件大小(例如:10M, 2G)')
    parser.add_argument('-w', '--workers', type=int, default=4,
                       help='线程池工作线程数(默认:4)')
    args = parser.parse_args()

    search_results = search_excel_files(
        args.folder, 
        args.keywords,
        min_size=args.min_size,
        max_size=args.max_size,
        workers=args.workers
    )

    print("\n最终搜索结果已保存至:")
    print(f"- 实时日志:{os.path.join(args.folder, 'search_results.log')}")
    print(f"- 断点状态:{os.path.join(args.folder, 'search_status.txt')}")

再7

import os
import argparse
import pandas as pd
import threading
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor
from python_calamine.pandad import pandas_monkeypatch

# 应用calamine补丁替换pandas的Excel引擎
pandas_monkeypatch()

# 全局锁用于保证文件写入安全
result_lock = threading.Lock()
status_lock = threading.Lock()

class SearchManager:
    def __init__(self, folder, result_file="search_results.log", status_file="search_status.txt"):
        self.folder = folder
        self.result_file = os.path.join(folder, result_file)
        self.status_file = os.path.join(folder, status_file)
        
        # 初始化已完成文件记录
        self.completed_files = set()
        if os.path.exists(self.status_file):
            with open(self.status_file, 'r') as f:
                self.completed_files = set(f.read().splitlines())
        
        # 初始化结果文件(追加模式)
        if not os.path.exists(self.result_file):
            with open(self.result_file, 'w', encoding='utf-8') as f:
                f.write("文件路径,工作表名,单元格地址,单元格内容,关键词\n")

    def record_result(self, result):
        """线程安全地记录结果"""
        with result_lock:
            # 实时显示结果(显示前100个字符)
            display_content = result['cell_content'][:100].replace('\n', ' ')
            print(f"[实时发现] {result['file']} -> {result['sheet']}!{result['cell_address']}")
            print(f"  内容片段:{display_content}...")
            print(f"  匹配关键词:{result['keyword']}\n{'━'*50}")
            
            # 保存到结果文件(完整内容)
            with open(self.result_file, 'a', encoding='utf-8') as f:
                content = result['cell_content'].replace('\n', '\\n').replace(',', ',')
                f.write(f"{result['file']},{result['sheet']},{result['cell_address']},\"{content}\",{result['keyword']}\n")

    def mark_completed(self, file_path):
        """标记文件已完成处理"""
        with status_lock:
            with open(self.status_file, 'a') as f:
                f.write(f"{file_path}\n")
            self.completed_files.add(file_path)

def convert_size_to_bytes(size_str):
    """将人类可读的文件大小转换为字节数"""
    units = {'B': 1, 'K': 1024, 'M': 1024**2, 'G': 1024**3}
    if not size_str: return 0
    
    unit = size_str[-1].upper()
    if unit.isdigit():
        return int(size_str)
    value = float(size_str[:-1])
    return int(value * units.get(unit, 1))

def column_to_letter(col):
    """将列索引转换为Excel列字母"""
    letter = ''
    while col >= 0:
        letter = chr(col % 26 + 65) + letter
        col = col // 26 - 1
    return letter or 'A'

def process_single_file(file_path, keywords, manager):
    """处理单个文件并返回结果"""
    results = []
    try:
        with pd.ExcelFile(file_path, engine="calamine") as xls:
            for sheet_name in xls.sheet_names:
                df = xls.parse(
                    sheet_name,
                    header=None,
                    dtype=str,
                    na_filter=False,
                    engine="calamine"
                )
                
                # 遍历所有单元格
                for row_idx, row in df.iterrows():
                    for col_idx, cell in enumerate(row):
                        if pd.isna(cell):
                            continue
                        cell_value = str(cell)
                        for keyword in keywords:
                            if keyword in cell_value:
                                cell_address = f"{column_to_letter(col_idx)}{row_idx+1}"
                                result = {
                                    'file': file_path,
                                    'sheet': sheet_name,
                                    'cell_address': cell_address,
                                    'cell_content': cell_value,
                                    'keyword': keyword
                                }
                                results.append(result)
                                manager.record_result(result)
        # 标记文件完成处理
        manager.mark_completed(file_path)
    except Exception as e:
        print(f"\n错误处理文件 {file_path}: {str(e)}")
    return results

def search_excel_files(folder_path, keywords, min_size=None, max_size=None, workers=4):
    """支持断点续查的多线程搜索函数"""
    manager = SearchManager(folder_path)
    
    print("正在扫描并筛选Excel文件...")
    file_list = []
    
    # 转换文件大小单位
    min_bytes = convert_size_to_bytes(min_size) if min_size else 0
    max_bytes = convert_size_to_bytes(max_size) if max_size else float('inf')

    # 遍历文件并筛选
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.xlsx'):
                file_path = os.path.join(root, file)
                # 跳过已处理文件
                if file_path in manager.completed_files:
                    continue
                file_size = os.path.getsize(file_path)
                if min_bytes <= file_size <= max_bytes:
                    file_list.append(file_path)

    total_files = len(file_list)
    results = []
    
    with ThreadPoolExecutor(max_workers=workers) as executor:
        # 创建进度条
        with tqdm(total=total_files, desc="搜索进度", unit="file", ncols=100) as pbar:
            # 提交任务
            futures = []
            for file_path in file_list:
                future = executor.submit(process_single_file, file_path, keywords, manager)
                future.add_done_callback(lambda _: pbar.update(1))
                futures.append(future)
            
            # 收集结果
            for future in futures:
                try:
                    results.extend(future.result())
                except Exception as e:
                    print(f"\n任务执行错误: {str(e)}")
                pbar.set_postfix({"剩余文件": f"{total_files - pbar.n}"})

    print("\n最终搜索结果已保存至:")
    print(f"- 实时日志:{os.path.join(folder_path, 'search_results.log')}")
    print(f"- 断点状态:{os.path.join(folder_path, 'search_status.txt')}")
    return results

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='支持单元格内容输出的Excel搜索工具')
    parser.add_argument('folder', help='要搜索的文件夹路径')
    parser.add_argument('-k', '--keywords', nargs='+', required=True,
                       help='要搜索的关键词列表(用空格分隔)')
    parser.add_argument('--min-size', help='最小文件大小(例如:1M, 500K)')
    parser.add_argument('--max-size', help='最大文件大小(例如:10M, 2G)')
    parser.add_argument('-w', '--workers', type=int, default=4,
                       help='线程池工作线程数(默认:4)')
    args = parser.parse_args()

    search_results = search_excel_files(
        args.folder, 
        args.keywords,
        min_size=args.min_size,
        max_size=args.max_size,
        workers=args.workers
    )

再8

import os
import argparse
import pandas as pd
import threading
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor
from python_calamine.pandas import pandas_monkeypatch

# 应用calamine补丁替换pandas的Excel引擎
pandas_monkeypatch()

# 全局锁用于保证文件写入安全
result_lock = threading.Lock()
status_lock = threading.Lock()

class SearchManager:
    def __init__(self, folder, result_file="search_results.log", status_file="search_status.txt"):
        # ...(保持原有初始化逻辑不变)...

    def record_result(self, result):
        # ...(保持原有记录逻辑不变)...

    def mark_completed(self, file_path):
        # ...(保持原有标记逻辑不变)...

def convert_size_to_bytes(size_str):
    # ...(保持原有转换逻辑不变)...

def column_to_letter(col):
    # ...(保持原有转换逻辑不变)...

def process_single_file(file_path, keywords, exclude_keywords, manager):
    """处理单个文件并返回结果(增加排除关键词逻辑)"""
    results = []
    try:
        with pd.ExcelFile(file_path, engine="calamine") as xls:
            for sheet_name in xls.sheet_names:
                df = xls.parse(
                    sheet_name,
                    header=None,
                    dtype=str,
                    na_filter=False,
                    engine="calamine"
                )
                
                # 遍历所有单元格
                for row_idx, row in df.iterrows():
                    for col_idx, cell in enumerate(row):
                        if pd.isna(cell):
                            continue
                        cell_value = str(cell)
                        
                        # 检查排除关键词
                        if any(ex_kw in cell_value for ex_kw in exclude_keywords):
                            continue
                            
                        # 检查包含关键词
                        matched_keywords = [kw for kw in keywords if kw in cell_value]
                        for keyword in matched_keywords:
                            cell_address = f"{column_to_letter(col_idx)}{row_idx+1}"
                            result = {
                                'file': file_path,
                                'sheet': sheet_name,
                                'cell_address': cell_address,
                                'cell_content': cell_value,
                                'keyword': keyword
                            }
                            results.append(result)
                            manager.record_result(result)
        manager.mark_completed(file_path)
    except Exception as e:
        print(f"\n错误处理文件 {file_path}: {str(e)}")
    return results

def search_excel_files(folder_path, keywords, exclude_keywords, min_size=None, max_size=None, workers=4):
    """支持排除关键词的搜索函数"""
    manager = SearchManager(folder_path)
    
    print("正在扫描并筛选Excel文件...")
    file_list = []
    
    # 转换文件大小单位
    min_bytes = convert_size_to_bytes(min_size) if min_size else 0
    max_bytes = convert_size_to_bytes(max_size) if max_size else float('inf')

    # 遍历文件并筛选
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.xlsx'):
                file_path = os.path.join(root, file)
                if file_path in manager.completed_files:
                    continue
                file_size = os.path.getsize(file_path)
                if min_bytes <= file_size <= max_bytes:
                    file_list.append(file_path)

    total_files = len(file_list)
    results = []
    
    with ThreadPoolExecutor(max_workers=workers) as executor:
        with tqdm(total=total_files, desc="搜索进度", unit="file", ncols=100) as pbar:
            futures = []
            for file_path in file_list:
                future = executor.submit(
                    process_single_file, 
                    file_path, 
                    keywords,
                    exclude_keywords,  # 传递排除关键词
                    manager
                )
                future.add_done_callback(lambda _: pbar.update(1))
                futures.append(future)
            
            for future in futures:
                try:
                    results.extend(future.result())
                except Exception as e:
                    print(f"\n任务执行错误: {str(e)}")
                pbar.set_postfix({"剩余文件": f"{total_files - pbar.n}"})

    print("\n最终搜索结果已保存至:")
    print(f"- 实时日志:{os.path.join(folder_path, 'search_results.log')}")
    print(f"- 断点状态:{os.path.join(folder_path, 'search_status.txt')}")
    return results

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='支持关键词排除的Excel搜索工具')
    parser.add_argument('folder', help='要搜索的文件夹路径')
    parser.add_argument('-k', '--keywords', nargs='+', required=True,
                       help='要搜索的关键词列表(用空格分隔)')
    parser.add_argument('-e', '--exclude', nargs='+', default=[],
                       help='要排除的关键词列表(用空格分隔)')
    parser.add_argument('--min-size', help='最小文件大小(例如:1M, 500K)')
    parser.add_argument('--max-size', help='最大文件大小(例如:10M, 2G)')
    parser.add_argument('-w', '--workers', type=int, default=4,
                       help='线程池工作线程数(默认:4)')
    args = parser.parse_args()

    search_results = search_excel_files(
        args.folder, 
        args.keywords,
        exclude_keywords=args.exclude,  # 新增排除关键词参数
        min_size=args.min_size,
        max_size=args.max_size,
        workers=args.workers
    )
import os
import shutil
from tqdm import tqdm

def move_directory_with_progress(src, dst):
    """移动目录并显示进度条
    
    Args:
        src (str): 源目录路径
        dst (str): 目标目录路径
    """
    # 获取源目录的基本名称
    src_base = os.path.basename(src)
    
    # 确定最终目标路径
    if os.path.exists(dst) and os.path.isdir(dst):
        final_dst = os.path.join(dst, src_base)
    else:
        final_dst = dst
    
    # 确保目标父目录存在
    os.makedirs(os.path.dirname(final_dst), exist_ok=True)
    
    # 计算总文件数用于进度条
    total_files = 0
    for root, _, files in os.walk(src):
        total_files += len(files)
    
    # 使用 tqdm 创建进度条
    with tqdm(total=total_files, unit='file', desc='Moving files') as pbar:
        # 自定义复制函数用于更新进度条
        def copy_with_progress(src_path, dst_path):
            shutil.copy2(src_path, dst_path)
            pbar.update(1)
        
        # 执行目录移动(复制+删除)
        try:
            # 复制目录结构
            shutil.copytree(
                src, 
                final_dst, 
                copy_function=copy_with_progress,
                dirs_exist_ok=True
            )
            # 删除原目录
            shutil.rmtree(src)
        except Exception as e:
            # 错误处理:清理部分复制的文件
            if os.path.exists(final_dst):
                shutil.rmtree(final_dst)
            raise RuntimeError(f"移动失败: {str(e)}")

if __name__ == "__main__":
    # 配置你的路径
    pathA = "/path/to/source/directory"  # 替换为你的源目录
    pathB = "/path/to/destination"        # 替换为你的目标目录
    
    # 执行移动操作
    move_directory_with_progress(pathA, pathB)
    print(f"\n操作完成!'{pathA}' 已移动到 '{pathB}'")
import os
import shutil
import sys
from tqdm import tqdm

def move_directory_with_progress(src, dst):
    """移动目录并显示进度条(兼容所有 Python 3.x 版本)"""
    # 获取源目录名称
    src_name = os.path.basename(src.rstrip(os.sep))
    
    # 确定最终目标路径
    if os.path.isdir(dst):
        final_dst = os.path.join(dst, src_name)
    else:
        final_dst = dst
    
    # 确保目标父目录存在
    os.makedirs(os.path.dirname(final_dst), exist_ok=True)
    
    # 计算总文件数
    total_files = 0
    for root, _, files in os.walk(src):
        total_files += len(files)
    
    # 使用 tqdm 创建进度条
    with tqdm(total=total_files, unit='file', desc='Moving files') as pbar:
        # 手动复制目录结构
        for root, dirs, files in os.walk(src):
            # 计算相对路径
            rel_path = os.path.relpath(root, src)
            dest_dir = os.path.join(final_dst, rel_path)
            
            # 创建目标目录(如果不存在)
            if not os.path.exists(dest_dir):
                os.makedirs(dest_dir)
            
            # 复制文件
            for file in files:
                src_file = os.path.join(root, file)
                dest_file = os.path.join(dest_dir, file)
                
                # 复制文件并保留元数据
                shutil.copy2(src_file, dest_file)
                pbar.update(1)
        
        # 复制完成后删除源目录
        shutil.rmtree(src)

if __name__ == "__main__":
    # 配置你的路径
    pathA = "/path/to/source/directory"  # 替换为你的源目录
    pathB = "/path/to/destination"        # 替换为你的目标目录
    
    try:
        # 检查路径是否存在
        if not os.path.exists(pathA):
            print(f"错误:源路径 '{pathA}' 不存在")
            sys.exit(1)
            
        print(f"开始移动: {pathA} -> {pathB}")
        move_directory_with_progress(pathA, pathB)
        print(f"\n操作完成!'{pathA}' 已成功移动到 '{pathB}'")
    except Exception as e:
        print(f"\n移动过程中出错: {str(e)}")
        sys.exit(1)

About

Training on usage of repository

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors