import pandas as pd import os import glob class vault(): def __init__(self): """Простой класс для работы с Excel файлами""" pass def file_filter(self, dir_name): """Алгоритм 1: Перебор файлов в директории""" print(f"Ищем в директории: {dir_name}") print(f"Полный путь: {os.path.abspath(dir_name)}") if not os.path.exists(dir_name): print(f"Директория {dir_name} не существует") return [] # Показываем все файлы в директории all_files = os.listdir(dir_name) print(f"Все файлы в директории: {len(all_files)} файлов") # Поиск всех xls и xlsx файлов pattern_xlsx = os.path.join(dir_name, "*.xlsx") pattern_xls = os.path.join(dir_name, "*.xls") print(f"Паттерн поиска xlsx: {pattern_xlsx}") print(f"Паттерн поиска xls: {pattern_xls}") xlsx_files = glob.glob(pattern_xlsx) xls_files = glob.glob(pattern_xls) # Объединяем все Excel файлы excel_files = xlsx_files + xls_files # Исключаем временные файлы Excel (начинающиеся с ~$) excel_files = [f for f in excel_files if not os.path.basename(f).startswith('~$')] print(f"Найдено {len(excel_files)} Excel файлов:") for file in excel_files: print(f" - {os.path.basename(file)}") return excel_files def open_xlsx(self, file_name, header_rows=1, row_filter=None): """Алгоритм 2: Перебор строк документа с настраиваемой шапкой и фильтром""" try: # Пробуем разные движки для чтения файлов if file_name.endswith('.xls'): # Для старых файлов .xls используем xlrd df = pd.read_excel(file_name, header=list(range(header_rows)), engine='xlrd') else: # Для .xlsx используем openpyxl df = pd.read_excel(file_name, header=list(range(header_rows)), engine='openpyxl') print(f"Файл {os.path.basename(file_name)}: загружено {len(df)} строк") # Применяем пользовательский фильтр если он задан if row_filter and callable(row_filter): original_count = len(df) df = df[df.apply(row_filter, axis=1)] filtered_count = len(df) print(f"После фильтрации: {filtered_count} строк (исключено {original_count - filtered_count})") return df except Exception as e: print(f"Ошибка при открытии файла {file_name}: {e}") # Пробуем альтернативный способ try: print(f"Пробуем альтернативный движок для {os.path.basename(file_name)}") df = pd.read_excel(file_name, header=list(range(header_rows)), engine='calamine') print(f"Успешно загружено {len(df)} строк альтернативным способом") if row_filter and callable(row_filter): original_count = len(df) df = df[df.apply(row_filter, axis=1)] filtered_count = len(df) print(f"После фильтрации: {filtered_count} строк") return df except Exception as e2: print(f"Альтернативный способ тоже не сработал: {e2}") return pd.DataFrame() def merge_files(self, dir_name, output_file="merged.xlsx", header_rows=1, row_filter=None): """Объединяет файлы с настройками шапки и фильтра""" # Алгоритм 1: находим файлы files = self.file_filter(dir_name) if not files: print("Файлы не найдены") return all_data = [] # Алгоритм 2: обрабатываем каждый файл for file_path in files: df = self.open_xlsx(file_path, header_rows, row_filter) if not df.empty: # Добавляем информацию об источнике df['_источник'] = os.path.basename(file_path) all_data.append(df) if all_data: # Объединяем все данные result = pd.concat(all_data, ignore_index=True) # Сохраняем результат result.to_excel(output_file, index=False) print(f"\nОбъединено {len(result)} строк в файл {output_file}") else: print("Нет данных для объединения") # Примеры использования if __name__ == "__main__": vault_instance = vault() print("\n=== Пример 3: С фильтром строк ===") def my_filter(row): # Исключаем строки где первый столбец пустой return not pd.isna(row.iloc[4]) and row.iloc[0] != "" # Ищем файлы в папке ПРИЕММ и сохраняем результат как merged.xlsx # Попробуйте с разными вариантами имени папки: vault_instance.merge_files(".\Свод Нозология", "merged.xlsx", row_filter=my_filter) # или # vault_instance.merge_files(r"ПРИЕММ", "merged.xlsx", row_filter=my_filter)