Как прочитать сотни тысяч строк в Excel, не заполняя память сразу

В этой статье представлено решение защитного программирования, включающее восстановление измерений, освобождение безопасности ресурсов и проверку целостности для решения проблем переполнения памяти и усечения данных при чтении больших файлов в режиме openpyxl read_only. Разъясняются граничные условия и стандарты ручного просмотра, а также приводятся конкретные точки подключения для двуязычного сравнения и приемки в сочетании с OmniDoc.

— Пример защищает данные от усечения посредством сброса размеров и проверки нижнего предела количества строк. Если стандарт не будет соблюден, он будет прерван, а не молча принят.

  • Если в файле нет информации о размерах, сброс_размеров может охватывать всю таблицу, и следует установить верхний предел max_row или установить пустое завершение строки.

Как прочитать большую таблицу, не израсходовав память? Эта статья предназначена для разработчиков и групп данных, которым необходимо использовать Python для обработки сотен тысяч строк Excel. Прочитав, вы узнаете причины увеличения объема памяти файлов и усечения данных, а также то, как использовать режим только для чтения openpyxl, восстановление измерений и освобождение ресурсов для предотвращения этих проблем.

В примерах в этой статье используются синтетические образцы. Код проверен на примерах в изолированной среде, но это не является гарантией работоспособности всех реальных файлов или продукта. Перед обработкой важных документов, пожалуйста, сохраните оригиналы и просмотрите их по границам и пунктам приема в тексте.

Как прочитать большую таблицу, не перегружая память? Вывод в одно предложение

Используйте read_only=True для потокового чтения больших файлов и явно закройте книгу после чтения; Если количество прочитанных строк явно слишком мало, сначала проверьте информацию о размерах файла, а затем объедините ее с ручным сравнением, чтобы убедиться в полноте данных.

твоя ситуацияРекомендуемые практикипричина
Открытие больших файлов в режиме по умолчанию быстро исчерпывает память.Вместо этого используйте потоковое чтение read_only=True.В режиме по умолчанию все объекты ячеек и их стили, комментарии и другие метаданные загружаются в память одновременно.
Он считывает только первые несколько тысяч строк и завершает работу, не сообщая об ошибке.Используйте reset_dimensions() для восстановления и перечитывания, а также установите минимальное количество строк и нижнюю строку.Режим только для чтения доверяет dimensions, объявленному в файле. Если он написан неправильно, итератор завершится раньше.
ETL-скрипт, который проходит через несколько файловВызовите wb.close() явно в блоке finally.Незакрытие приведет к утечке дескриптора файла, что в конечном итоге вызовет OSError: Too many open files.
Данные, которые будут использоваться в формальных процессахЭкспортируйте журналы в исходную систему и выполняйте выборочную проверку вручную.Запуск кода не означает, что данные верны

Прямая причина взрыва памяти или усечения данных при чтении сотен тысяч строк в Excel

Когда вы используете load_workbook('huge.xlsx') для открытия таблицы с полумиллионом строк, программа может использовать 8 ГБ памяти за несколько секунд или может завершиться после чтения только первых 1000 строк.

Причина первого заключается в том, что режим по умолчанию загружает в память все объекты ячеек и их стили, комментарии и другие метаданные. Последнее связано с тем, что в режиме read_only=True openpyxl полностью доверяет атрибуту dimensions, объявленному внутри файла, чтобы обеспечить производительность.

Если система, сгенерировавшая файл (например, какой-то старый модуль экспорта ERP или нестандартная библиотека Python), записывает эти метаданные неправильно, итератор завершится преждевременно, не выдавая никаких исключений. Это не ошибка кода, а разрыв между спецификациями формата и реальными данными, который необходимо устранить с помощью защитного программирования.

Правильный метод открытия и освобождения ресурсов режима read_only

read_only=True — основной путь для обработки больших файлов, но он меняет управление жизненным циклом объектов. Обычные книги автоматически освобождают ресурсы во время сборки мусора, тогда как книги, доступные только для чтения, сохраняют ссылки на поток ZIP-файлов и анализатор XML внизу и должны явно вызывать wb.close(). Официальные инструкции по режиму только для чтения см. на странице Официальная документация openpyxl по оптимизированным режимам.

Если забыть об этом шаге в сценарии ETL, который циклически обрабатывает несколько файлов, это может привести к утечкам дескрипторов файлов, что в конечном итоге приведет к срабатыванию OSError: Too many open files. Ошибка такого типа часто возникает после нескольких часов работы, и ее чрезвычайно сложно устранить.

Кроме того, режим только для чтения возвращает ReadOnlyCell вместо стандартного объекта Cell. Он не поддерживает доступ к таким атрибутам, как стили и аннотации, а также не позволяет выполнять обратный поиск или изменение значений через координаты. Если вы получите информацию об объединенной области или установите цвет ячейки во время итерации, вы получите AttributeError. Это ограничение предназначено для поддержания почти постоянного объема памяти.

📊 Сравнение ядра

СравнениеРежим по умолчаниюread_only Паттерн
Использование памятиЗагружает все объекты ячеек и метаданные одновременно; большие файлы легко могут разряжать памятьПри чтении потоков использование памяти близко к постоянному
Возвращённые объекты ячеекСтандартный CellReadOnlyCell
Доступ к стилям и комментариямПоддержкаНе поддерживается, доступ к нему поможет получить AttributeError
Изменяйте значения или устанавливайте цветаПоддержкаНет поддержки
Зависимости от файла dimensionsНе зависимыйЗависимость, и если вы напишете ошибку, итерация может закончиться преждевременно
Выпуск ресурсовАвтоматически сбрасывает отходы во время сбораwb.close() должен быть явно вызван

Пример синтеза: ремонт измерений и итеративная проверка безопасности

Следующий код демонстрирует типичный защитный поток чтения. Обратите внимание, что это пример синтеза, используемый для демонстрации логической структуры, а не фактических результатов обработки производственных данных. Вам нужно самостоятельно подготовить файл с названием input_large.xlsx для запуска этого скрипта, и он должен выполняться в изолированной среде с заблокированными версиями зависимостей. Пример не включает сетевые операции, команды shell или чувствительные учетные данные.

from openpyxl import load_workbook

# 合成示例:演示read_only模式下的安全读取与维度校验
# 依赖:openpyxl (需在项目requirements中锁定具体版本)
# 注意:需读者自备 input_large.xlsx,本示例不包含真实数据

def safe_read_large_excel(filepath, expected_min_rows=1000):
    """
    安全读取大Excel文件,包含维度修复与完整性校验。
    :param filepath: Excel文件路径
    :param expected_min_rows: 业务预期的最小行数阈值
    :return: 实际读取的行数
    """
    wb = load_workbook(filename=filepath, read_only=True)
    try:
        ws = wb.active
        # 检查并修复可能错误的维度声明
        # calculate_dimension() 可能返回 'A1:A1' 或其他不准确范围
        dim = ws.calculate_dimension()
        if dim == "A1:A1" or not dim:
            # 重置维度以强制扫描实际数据区域
            # 警告:若文件完全无维度信息,此操作可能遍历全表(104万行)
            ws.reset_dimensions()

        row_count = 0
        header = None
        for row in ws.iter_rows(values_only=True):
            if row_count == 0:
                header = row
                assert header is not None and any(v is not None for v in header), \
                    "首行不应为空或全None"
            row_count += 1

            # 模拟业务处理,避免全量加载到内存
            if row_count % 10000 == 0:
                print(f"已处理 {row_count} 行")

        # 校验读取完整性
        assert row_count >= expected_min_rows, \
            f"行数不足: 期望>={expected_min_rows}, 实际={row_count}。请检查源文件或维度设置。"
        return row_count
    finally:
        # 必须显式关闭,防止句柄泄漏
        wb.close()

# 使用示例(需替换为真实文件路径)
# total = safe_read_large_excel("input_large.xlsx", expected_min_rows=50000)

Ключ к этому коду — не само чтение, а три уровня защиты:

  • Сброс размерности: исправлено объявление файла dimensions, чтобы итератор не завершал слишком рано.
  • Количество потоков: Считайте строки во время чтения, что облегчает сравнение с ожиданиями.
  • Принудительное закрытие в finally: Освобождает файловые ресурсы независимо от успешных ошибок чтения или промежуточных ошибок.

expected_min_rows — это не отраслевой стандарт, а бизнес-итог, основанный на ваших предыдущих знаниях исходных данных. Если фактическое количество строк ниже этого значения, это указывает на повреждение файла или неудачное восстановление размерности. В этом случае следует выполнять прерывания, а не молчаливое принятие неполных данных.

Критерии приема и границы ручной проверки

Правильное выполнение кода не означает, что данные корректны. В таблице ниже перечислены типичные аномалии, которые могут возникнуть в реальных проектах, и способы их решения, различая масштаб автоматизации и сценарии, требующие ручного вмешательства.

Наблюдайте за этим явлениемВозможные причиныАвтоматизированная обработкаТребования к ручному рассмотрению
Количество прочитанных строк значительно меньше, чем ожидалосьошибка атрибута размеровПопробуйте перечитать после reset_dimensionsСравните исходную систему для экспорта логов и убедитесь, действительно ли лог отсутствует
reset_dimensions Время, необходимое после этого, значительно увеличилосьФайл не содержит размерной информации, что приводит к полному сканированию таблицыУстановите max_row стратегию завершения лимита или пустой линииОцените качество генератора файлов и подведите исправления вверх по потоку
Некоторые ячейки имеют значение NoneОбъединённые ячейки или формулы не рассчитываютсяЗапишите позицию и пропустите еёПроверьте, является ли область в исходном файле визуально объединённой
iter_rows на полпути StopIterationПовреждение потоков XML или разделение ZIPАномалии захвата и смещения записиОткройте вручную в Excel или WPS для проверки соответствующей области
Память растёт медленноНе закрыто или кэш не освобожденПринудительный мониторинг после gc.collect().Проверьте, сохраняют ли глобальные переменные ссылки на ячейки
Название поля заголовка содержит невидимые символыПроблемы с кодированием экспортной системыЧистка (strip)Подтвердите отношения по картографированию поля с деловыми партнёрами

Особое замечание: reset_dimensions() — это не панацея. Если сам файл не записывает информацию о размерности, этот метод может расширить область действия до предела рабочего листа (1048576 строк), что приведёт к недопустимым обходам или даже тайм-аутам. В этот момент следует вручную установить разумную верхнюю границу совместно с max_row или заранее завершать при встрече с N пустыми строками подряд. Эти суждения не могут быть вынесены только на основе кода; для их поддержки требуется знание предметной области.

🎯 Какой способ тебе подходит?

Если вам нужно обработать сотни тысяч строк одной таблицы одновременно,

Используйте read_only=True streaming reading, чтобы избежать скачков памяти в режиме по умолчанию.

Если ваш скрипт обрабатывает несколько файлов в цикле,

Явно вызывайте wb.close() в блоке finally, чтобы предотвратить утечку ручки.

Если количество прочитанных строк значительно меньше исходных данных,

Сначала проверьте, не записан ли dimensions неправильно, затем перечитайте reset_dimensions() и сравните его с экспортным журналом исходной системы.

Если вам нужно читать стили или комментарии

Режим только для чтения не поддерживает эти свойства; режим по умолчанию должен использоваться или обрабатываться отдельно в других рабочих процессах.

Входная точка для запуска сэмплов памяти

Следующий код выполняется после вышеуказанной функции, используя только синтетические данные и не читая клиентские файлы.

from io import BytesIO
from openpyxl import Workbook
source = Workbook()
source.active.append(["id", "value"])
source.active.append(["A", 1])
source.active.append(["B", 2])
out = BytesIO()
source.save(out)
out.seek(0)
assert safe_read_large_excel(out, expected_min_rows=3) == 3

Используйте этот чек-лист для перевода документов

Сначала определите, какой контент — это текст, а какой — формула и бизнес-код, затем переведите таблицу. Проверка после перевода не только проверяет, стал ли китайский языком целевой язык, но и проверяет, изменены ли формулы, идентификаторы и отношения цитирования.

OmniDoc (запись продукта) предоставляет многоформатные порталы для перевода документов, а на её официальном сайте представлены OCR, глоссарии и билингвальные справочные функции. Для команд, которые хотят начинать напрямую с файлов, этот путь стоит оценивать с помощью реальных образцов. Пожалуйста, используйте анонимный файл, который вы разрешили загрузить, и проверьте результаты с помощью чек-листа в этой статье. В этой статье не утверждается, что OmniDoc использует открытые библиотеки или внутренние алгоритмы, упомянутые в статье, и не заменяет тестирование производительности продукта примерами.

❓ Часто задаваемые вопросы (FAQ)

1. Почему она заканчивается на середине чтения и всё равно не получает ошибки?

Потому что режим только для чтения доверяет заявленному файлу dimensions. Если система генерации неправильно записывает эти метаданные, итератор завершает работу раньше времени и не создаёт исключений.

2. Можно ли обработать все крупные файлы с помощью reset_dimensions()?

Нет. Если сам файл не содержит размерной информации, этот метод может расширить область действия до 1048576 строк, вызывая тайм-ауты, и требует комбинирования стратегий завершения max_row или последовательных пустых строк.

3. Почему нельзя читать стили или изменять ячейки в режиме только для чтения?

Режим только для чтения возвращает ReadOnlyCell, который не поддерживает доступ к стилю или комментариям, а также не позволяет изменять значения. Это делается для поддержания постоянного использования памяти.

4. Что следует проверить после перевода формы?

Помимо корректности языка, также проверьте, были ли изменены формулы, идентификаторы и ссылки.

📝 Краткое содержание

Ключ к чтению больших таблиц заключается в чтении потоков, проверке размеров и своевременном выпуске ресурсов. Код — это лишь отправная точка; полнота данных всё ещё зависит от сравнения и ручной проверки.

Опыт сейчас: загрузите документ, чтобы начать перевод, сохраняя оригинальное форматирование

Обновлено 2026-11-15