Openpyxl не закрывает книгу Excel в режиме только для чтения
Я хочу, чтобы иметь возможность читать файл Excel в Python, держать скрипт Python, выполняющий что-то еще после завершения чтения, и иметь возможность редактировать файл Excel в другом процессе тем временем. Я использую python 2.7 и openpyxl.
В настоящее время это выглядит так:
from openpyxl import load_workbook def get_excel_data(): OESwb = load_workbook(filename = OESconfigFile, data_only=True, read_only=True) ws = OESwb.get_sheet_by_name('MC01') aValue = ws['A1'].value return aValue val = get_excel_data()
После запуска функции файл Excel по-прежнему заблокирован для доступа к другим процессам (он дает ошибку «filename» в настоящее время используется. Повторите попытку позже »), даже если я больше не хочу читать его на Python.
- Получить рабочий лист по имени в интерфейсе автоматизации объектной модели Excel
- Отчеты Aeroo: ошибка при создании отчета. ASCII
- Условное форматирование не работает после сохранения с помощью openpyxl
- Цветные ячейки excel на основе условия соответствия в python
- получить выбранный цвет заливки с помощью openpyxl ячейки, используя условное форматирование
Как закрыть файл из моего сценария? Я пробовал OESwb.close (), но он дает ошибку «Объект« Рабочая книга »не имеет атрибута« закрыть ». Я нашел этот пост, но он, похоже, не помогает.
EDIT: Кажется, OESwb.save ('filename.xlsx') работает, но только если read_only = False. Тем не менее, было бы идеально, чтобы иметь возможность закрыть файл и все еще находиться в режиме readonly. Похоже, что это ошибка с openpyxl, так как она должна закрыть файл после завершения загрузки load_workbook.
- Разбор в python, чтобы преуспеть
- Как настроить заливку ячеек прозрачным / без заполнения
- Erro при импорте xlsx: неверный режим ('rb') или имя файла: 'C: \\ directory \\ IQ_data.xlsx'
- Чтение значений или строк Charcter из CSV-листа
- Проблемы с файлом excel. XLRDError: неподдерживаемый формат или поврежденный файл: какой файл это?
- Отфильтруйте данные mySQL при использовании fetchall () перед передачей строк в Excel через DataNitro
- Открытие неизвестного имени файла Excel с использованием Python
- Установите рабочий лист.hide_gridlines (2) в определенный диапазон ячеек
wb._archive.close()
Работает также с use_iterator.
Я также обнаружил, что это проблема, и думаю, что странно, что книги не имеют близкого метода.
Решение, которое я придумал, было менеджером контекста, который «закрывает» файл для меня, так что я не добавлял бессмысленные сэйвы в свой код каждый раз, когда читаю электронную таблицу.
@contextlib.contextmanager def load_worksheet_with_close(filename, *args, **kwargs): ''' Open an openpyxl worksheet and automatically close it when finished. ''' wb = openpyxl.load_workbook(filename, *args, **kwargs) yield wb # Create path in temporary directory and write workbook there to force # it to close path = os.path.join(tempfile.gettempdir(), os.path.basename(filename)) wb.save(path) os.remove(path)
Чтобы использовать его:
with load_worksheet_with_close('myworkbook.xlsx') as wb: # Do things with workbook
Чтобы закрыть, я считаю, что вам нужно сохранить файл:
OESwb.save('filename.xlsx')
Надеюсь это поможет.
Я пробовал все эти решения для закрытия файла xlsx в режиме только для чтения, и ни один из них не выполняет эту работу. Я, наконец, закончил использование файла in-mem:
with open(xlsx_filename, "rb") as f: in_mem_file = io.BytesIO(f.read()) wb = load_workbook(in_mem_file, read_only=True)
Можете даже загружаться быстрее и не нужно беспокоиться о закрытии чего-либо.
Можешь попробовать:
wb = None
освободить ресурсы и загрузить его снова, как только вам это понадобится, в той же или другой переменной.
Используйте OESwb._archive.close()
Это закроет дополнительную дескриптор файла ZipFile, который был 'read_only=True'
в режиме 'read_only=True'
. Помните, после закрытия вы не смогли прочитать больше данных из OESwb
. Помните, что это обходное решение, и _archive
можно удалить в будущей версии.
По какой-то драконовской причине stackoverflow позволит мне опубликовать ответ, но мне не хватает «репутации» для комментариев или голосования, поэтому мы здесь.
Принятый ответ wb._archive.close()
не работал для меня. Возможно, это связано с тем, что я использую режим только для чтения. Он может нормально работать в режиме «нормальный».
Ответ bmiller – это единственный ответ, который сработал и для меня:
with open(xlsx_filename, "rb") as f: in_mem_file = io.BytesIO(f.read()) wb = load_workbook(in_mem_file, read_only=True)
И, по его словам, это быстрее при загрузке с open () или только с использованием только для чтения.
Мой рабочий код, основанный на ответе bmiller:
import os xlsx_filename=r'C:/location/of/file.xlsx') with open(xlsx_filename, "rb") as f: in_mem_file = io.BytesIO(f.read()) wb = openpyxl.load_workbook(in_mem_file, read_only=True)