Не сохраняйте повторно Excel, предоставленный клиентом напрямую: сначала проверьте внешние ссылки
Keep_vba=True — это политика хранения, а не свидетельство «обнаружения макроса». Следующее только проверяет, существует ли ZIP-пакет vbaProject.bin и компоненты внешней ссылки; наличие компонентов не означает, что контент безопасен, макросы действительны или внешние цели доступны. Макросы не будут выполняться, а ссылки посещаться не будут.
— По умолчанию для openpyxl значение Keep_vba равно False. Прямая загрузка и последующее сохранение приведут к удалению проекта VBA.
- По умолчанию для параметра Keep_links установлено значение True, сохраняются только определения ссылок, а работоспособность кэшей внешних данных после перезагрузки не гарантируется.
— Параметры Keep_links и Keep_vba недействительны в режиме только для чтения, и операции, пытающиеся сохранить эти функции, завершатся неудачей.
- Проверка учитывает только компоненты VBA и внешние ссылки в ZIP-пакете. Наличие компонентов не означает, что контент безопасен или макросы действительны.
Excel, отправленный клиентом, открывается нормально локально, но после обработки скриптом Python или загрузки в систему формула может измениться на #REF!, раскрывающееся меню исчезнет или даже не будет открыто. Обычно это не повреждение файла, а скорее автоматизированный инструмент, который не сохранил неповрежденным кеш внешних ссылок или макросы VBA при повторном сохранении.
Эта статья написана для разработчиков и операторов, которым необходимо использовать сценарии для пакетной обработки Excel. Ниже объясняется, какая информация будет потеряна при загрузке openpyxl по умолчанию, дается идея синтетической выборочной проверки и перечисляются границы, которые требуют ручной проверки во время приемки. Прочитав это, вы сможете определить, что необходимо проверить перед сохранением документа.
Вывод в одном предложении: перед повторным сохранением Excel проведите инвентаризацию внешних ссылок и компонентов VBA.
Сначала подтвердите, есть ли в пакете файлов проекты VBA и компоненты внешних ссылок, затем определитесь с параметрами загрузки и сохраните процесс проверки вручную во время принятия.
| твоя ситуация | Рекомендуемые практики | причина |
|---|---|---|
| Пакет файлов находится в vbaProject.bin. | Подскажет, что он содержит контент, который нужно просмотреть отдельно, и макрос не будет выполнен. | Наличие компонента не означает, что макрос действителен или содержимое безопасно. |
| В пакете файлов есть компоненты внешней ссылки. | Записывает свое местоположение внутри пакета, не получает доступа к цели | Сценарий только выполняет инвентаризацию и не проверяет, доступна ли цель. |
| Загрузить с помощью Keep_vba=True | Думайте об этом как о стратегии загрузки | Keep_vba=True — это политика хранения, а не свидетельство обнаружения макроса. |
##Почему при загрузке по умолчанию теряется ключевая информация
В официальной документации openpyxl указано, что load_workbook имеет четкие границы для обработки данных, не являющихся ячейками. keep_links по умолчанию имеет значение True, которое сохраняет определение ссылки в XML, но не гарантирует, что внешний кэш данных (кэшированные значения) будет по-прежнему действителен после перезагрузки. После того как вы покинете исходную сетевую среду или путь к исходному файлу, Excel все равно может сообщать об ошибке при обновлении.
keep_vba по умолчанию равен False. Если исходный файл содержит макросы, проект VBA по умолчанию будет удален после загрузки и сохранения. Такие объекты, как диаграммы и фигуры, также могут игнорироваться при чтении.
Это не баги, а функциональные границы самой библиотеки. При работе с файлами производственного уровня вам следует явно объявить политику хранения, а не предполагать, что инструмент автоматически сохранит все функции.
Синтетические примеры и подготовка тестовых файлов
Чтобы безопасно продемонстрировать этот механизм, рекомендуется построить синтетический сценарий, не опирающийся на реальные данные о клиентах.
Подготовьте тестовые файлы
- Создайте новую книгу Excel.
- Вставьте пустой модуль в редактор VBA (Alt+F11).
- Введите формулу
='[ExternalBook.xlsx]Sheet1'!$A$1в ячейку A1. Нет необходимости создавать настоящий внешний файл, просто сохраните эту ссылочную структуру. - Сохраните в формате
input_check.xlsmс поддержкой макросов.
Распространенные ошибки и ввод границ
— Код VBA автоматически отбрасывается при загрузке файлов с поддержкой макросов с использованием load_workbook('input_check.xlsm') по умолчанию и последующем сохранении как .xlsx. — Если keep_vba=True не указан при загрузке, но принудительно сохранен как .xlsm, Excel может отказаться открываться, поскольку заголовок файла не соответствует фактическому содержимому.
- В режиме только для чтения (
read_only=True) параметрыkeep_linksиkeep_vbaнедействительны, и любая попытка сохранить характеристики завершится неудачей.
Код проверки, зарезервированный для внешних ссылок и макросов
В следующем примере создается логика проверки памяти, чтобы продемонстрировать роль параметров.
from io import BytesIO
from zipfile import ZipFile
from openpyxl import Workbook
def inventory(raw):
with ZipFile(BytesIO(raw)) as z:
names = set(z.namelist())
return {"has_vba_part": "xl/vbaProject.bin" in names,
"external_link_parts": sorted(n for n in names if n.startswith("xl/externalLinks/externalLink") and n.endswith(".xml"))}
out = BytesIO()
Workbook().save(out)
assert inventory(out.getvalue()) == {"has_vba_part": False, "external_link_parts": []}
synthetic = BytesIO()
with ZipFile(synthetic, "w") as z:
z.writestr("xl/vbaProject.bin", b"not executable VBA; fixture only")
z.writestr("xl/externalLinks/externalLink1.xml", b"<fixture/>")
result = inventory(synthetic.getvalue())
assert result["has_vba_part"]
assert result["external_link_parts"] == ["xl/externalLinks/externalLink1.xml"]
Этот код является лишь обучающим примером, а не полноценным инструментом восстановления файлов, и не выполнялся в реальной производственной среде. Перед запуском убедитесь, что у вас есть input_check.xlsm, подготовленный, как указано выше.
📊 Сравнение ядра: параметры по умолчанию и зарезервированные параметры
| параметр | значение по умолчанию | эффект | граница |
|---|---|---|---|
| keep_links | True | Сохранение определений ссылок в XML | Внешний кэш данных не может быть действительным после перезагрузки. |
| keep_vba | False | Проекты VBA не сохраняются по умолчанию. | Установка значения True также не означает, что содержимое макроса безопасно или допустимо. |
| read_only | False | Загрузить в режиме только для чтения | Keep_links и Keep_vba недействительны в этом режиме. |
Критерии приемки и границы ручной проверки
Автоматизация не может охватить все крайние случаи Excel. Следующая таблица используется для того, чтобы определить, какие ситуации передаются в инвентаризацию сценариев, а какие требуют перехвата или ручной обработки.
| наблюдать | что делать | не следует предполагать |
|---|---|---|
| Компонент VBA существует | Приглашение содержит контент, требующий дополнительной проверки. | Не выполнять макрос |
| виджет внешней ссылки | Запишите местоположение внутри посылки | Не обращаться к цели |
| Оставить параметры включенными | рассматривается как стратегия загрузки | Не считается доказательством того, что макрос был обнаружен. |
Сценарий может проверить допустимость параметров, но не может гарантировать, что выходной файл доступен на бизнес-уровне. Например, keep_links=True успешно сохраняет определение ссылки. Если целевой сервер находится в автономном режиме, пользователь все равно получит сообщение об ошибке при обновлении в Excel. Такие проблемы выходят за рамки библиотеки обработки документов и требуют ручной проверки в процессе приемки.
Ссылки
Используйте этот контрольный список для перевода документов
При обработке таблиц, содержащих формулы и бизнес-коды, сначала различайте, какое содержимое является текстом, а какое — формулами, идентификаторами и бизнес-кодами, а затем переводите их. Проверка после перевода не только проверяет, был ли китайский язык преобразован в целевой язык, но также подтверждает, что формулы, идентификаторы и ссылочные отношения не были изменены.
OmniDoc (портал продуктов) предоставляет многоформатный портал для перевода документов, а на официальном сайте представлены функции оптического распознавания символов, глоссария и двуязычного сравнения. Для команд, которые хотят начать работать непосредственно с файлами, этот путь можно оценить на реальных примерах. Используйте десенсибилизированные файлы, на загрузку которых у вас есть разрешение, и используйте элементы проверки в этой статье, чтобы просмотреть результаты. Не утверждается, что OmniDoc использует библиотеки с открытым исходным кодом или внутренние алгоритмы, упомянутые в этой статье, и этот пример не заменяет тестирование производительности продукта.
🎯 Какой метод подходит вам?
Если вам нужно пакетно обработать файлы, содержащие макросы
Сначала используйте keep_vba=True, чтобы уточнить политику хранения, а затем сравните выходные результаты в тестовой среде. Не предполагайте, что макросы будут автоматически сохраняться.
Если ваш Excel содержит внешние ссылки
Сначала запишите расположение компонента ссылки в пакете и не обращайтесь к цели ссылки в скрипте. После повторного сохранения вручную подтвердите, нормально ли обновление.
Если вам просто нужно прочитать данные
Можно рассмотреть режим только для чтения, но имейте в виду, что параметры keep_links и keep_vba в этом режиме недействительны.
Если файл получен от клиента и содержит конфиденциальный контент
Сначала сохраните оригиналы, используйте для тестирования десенсибилизированные образцы, а затем просмотрите результаты в соответствии с пунктами приемки.
❓ Часто задаваемые вопросы (FAQ)
1. Означает ли Keep_links=True, что внешние ссылки должны быть доступны?
нет. keep_links сохраняет определение ссылки в XML. Нет никакой гарантии, что внешний кэш данных останется действительным после повторного кэширования. Обновление может по-прежнему сообщать об ошибке, если цель недоступна.
2. Что произойдет с макросом, если он будет загружен, а затем сохранен по умолчанию?
По умолчанию keep_vba имеет значение False, и проект VBA в исходном файле будет удален при сохранении. Если требуется сохранение, keep_vba=True следует задать явно.
3. Компонент VBA обнаружен, может ли скрипт определить, безопасен ли макрос?
не могу. Существование компонента не означает, что контент безопасен или макрос действителен. Скрипт не должен выполнять макрос и должен указать, что его необходимо просмотреть отдельно.
4. Можно ли сохранять ссылки и макросы в режиме только для чтения?
не могу. В режиме read_only=True параметры keep_links и keep_vba не действуют.
📝 Резюме
Перед повторным сохранением Excel проведите инвентаризацию компонентов VBA и внешних ссылок, уточните параметры загрузки и сохраните процесс проверки вручную. На следующем этапе вы можете подготовить три файла образца (чистые данные .xlsx, макросы .xlsm и внешние ссылки .xlsx) в тестовой среде, загрузить и сохранить их с параметрами по умолчанию и зарезервированными параметрами соответственно, а также записать фактические результаты в соответствии с таблицей выше. Только если вы знаете последствия каждого параметра в вашем наборе файлов, уместно развертывать сценарий в производственном процессе.
Попробуйте сейчас: загрузите документ, чтобы начать перевод, сохранив исходный макет.


