Перевод ИТ-инфраструктуры предприятий на операционные системы семейства Linux ставит перед разработчиками 1С сложные задачи. Одной из наиболее распространенных проблем является генерация многостраничных отчетов в формате Excel (xlsx) непосредственно на сервере под управлением Linux. Традиционный для Windows путь через COM-соединение и вызов приложения Excel.Application здесь не работает из-за отсутствия реестра Windows и самого пакета Microsoft Office.
В этой статье мы подробно проанализируем различные методы решения этой задачи — от простых штатных механизмов платформы 1С до продвинутых способов автоматизации с использованием внешних скриптов, библиотек и современных отечественных офисных пакетов.
Начиная с версии платформы 1С 8.3.12, разработчикам стал доступен мощный встроенный инструмент — класс ПакетОтображаемыхДокументов. Этот объект позволяет объединять несколько стандартных табличных документов в один пакет и сохранять их в виде книги Excel, где каждый исходный документ автоматически становится отдельной вкладкой (листом).
Главное преимущество этого метода заключается в том, что он полностью работает на стороне сервера (в том числе под управлением Linux) в фоновых и регламентных заданиях без привлечения стороннего программного обеспечения.
Рассмотрим пошагово процесс реализации этого механизма на практическом примере. Нам необходимо сформировать сводный отчет, состоящий из двух вкладок: "Продажи" и "Закупки".
// 1. Создаем исходные табличные документы, которые станут вкладками
ТабДокПродажи = Новый ТабличныйДокумент;
ТабДокЗакупки = Новый ТабличныйДокумент;
// На этом этапе заполняем табличные документы данными из запросов
// (например, методами Вывести() или Присоединить())
// Для примера просто запишем в них тестовый текст
ТабДокПродажи.Область("R1C1").Текст = "Отчет по продажам за текущий месяц";
ТабДокЗакупки.Область("R1C1").Текст = "Отчет по закупкам у поставщиков";
// 2. Инициализируем уникальный идентификатор для временного хранилища
УИД = Новый УникальныйИдентификатор;
// 3. Создаем объект пакета документов
Пакет = Новый ПакетОтображаемыхДокументов;
// 4. Добавляем первый лист (Продажи)
ЭлементПродажи = Пакет.Состав.Добавить();
ЭлементПродажи.Данные = ПоместитьВоВременноеХранилище(ТабДокПродажи, УИД);
// Важно: именно это свойство задает имя вкладки в итоговом Excel-файле
ЭлементПродажи.Наименование = "Продажи";
// 5. Добавляем второй лист (Закупки)
ЭлементЗакупки = Пакет.Состав.Добавить();
ЭлементЗакупки.Данные = ПоместитьВоВременноеХранилище(ТабДокЗакупки, УИД);
ЭлементЗакупки.Наименование = "Закупки";
// 6. Задаем путь сохранения файла на сервере Linux
// Обратите внимание на использование прямых слэшей для путей в Linux
ИмяФайла = "/tmp/СводныйОтчет_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd") + ".xlsx";
// 7. Записываем сформированный пакет в формате XLSX
Пакет.Записать(ИмяФайла, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
В результате выполнения этого кода на сервере Linux в каталоге /tmp будет создан полноценный многостраничный файл XLSX с двумя именованными листами. Обратите внимание, что свойство Наименование элемента состава пакета критически важно: если его не заполнить, платформа назовет листы по умолчанию ("Лист1", "Лист2").
Подводные камни встроенного метода:
ПакетОтображаемыхДокументов все листы книги могут создаваться в сгруппированном (выделенном) состоянии. Если пользователь откроет такой файл в Microsoft Excel и попробует изменить одну ячейку, эти изменения могут продублироваться на всех листах. Решается это ручной разгруппировкой пользователем (клик правой кнопкой мыши по вкладке -> "Разгруппировать листы").Формула), при экспорте пакета на Linux они сохранятся как обычный текст. Чтобы они пересчитались, пользователю потребуется активировать ячейку или использовать дополнительные методы постобработки.Для корпоративных систем, развернутых в рамках импортозамещения на российских дистрибутивах Linux (Astra Linux, РЕД ОС, Alt Linux), отличным решением является использование сертифицированного продукта «Библиотека для обработки электронных таблиц» от компании МойОфис.
Данная библиотека имеет статус «1С:Совместимо» и разработана специально для прямой интеграции с платформой 1С (начиная с версии 8.3.24) через программный интерфейс МойОфис SDK. Она позволяет программно создавать файлы форматов xlsx и ods на сервере Linux без использования COM и эмуляторов.
Преимущества работы через МойОфис SDK:
Если вам требуется сложная логика построения отчетов, условное форматирование, добавление графиков на отдельные листы или решение проблемы с неработающими формулами после экспорта из 1С, стандартных средств платформы может не хватить. В этом случае мы рекомендуем использовать связку «1С + Python».
На серверах под управлением Linux интерпретатор Python установлен по умолчанию практически в любом дистрибутиве. Для работы с Excel-файлами используются популярные библиотеки openpyxl или xlsxwriter.
Проанализируем алгоритм совместной работы 1С и Python:
ЗапуститьПриложение.xlsxwriter, применяет стили, строит диаграммы и сохраняет итоговый документ.Рассмотрим пример Python-скрипта (файл /opt/1c_scripts/create_excel.py), который собирает данные из двух временных JSON-файлов в один красивый Excel-файл с вкладками:
import json
import sys
import xlsxwriter
def build_report(sales_json_path, purchase_json_path, output_xlsx_path):
# Создаем новую книгу Excel
workbook = xlsxwriter.Workbook(output_xlsx_path)
# Добавляем стили оформления
header_format = workbook.add_format({
'bold': True,
'font_color': 'white',
'bg_color': '#1F497D',
'border': 1
})
# --- Вкладка "Продажи" ---
worksheet_sales = workbook.add_worksheet("Продажи")
with open(sales_json_path, 'r', encoding='utf-8') as f:
sales_data = json.load(f)
# Пишем заголовки
headers = ["Номенклатура", "Количество", "Сумма"]
for col_num, header in enumerate(headers):
worksheet_sales.write(0, col_num, header, header_format)
# Заполняем данными
for row_num, row_data in enumerate(sales_data, start=1):
worksheet_sales.write(row_num, 0, row_data.get("Item"))
worksheet_sales.write(row_num, 1, row_data.get("Qty"))
worksheet_sales.write(row_num, 2, row_data.get("Sum"))
# --- Вкладка "Закупки" ---
worksheet_purch = workbook.add_worksheet("Закупки")
with open(purchase_json_path, 'r', encoding='utf-8') as f:
purch_data = json.load(f)
# Пишем заголовки
for col_num, header in enumerate(headers):
worksheet_purch.write(0, col_num, header, header_format)
# Заполняем данными
for row_num, row_data in enumerate(purch_data, start=1):
worksheet_purch.write(row_num, 0, row_data.get("Item"))
worksheet_purch.write(row_num, 1, row_data.get("Qty"))
worksheet_purch.write(row_num, 2, row_data.get("Sum"))
# Закрываем и сохраняем книгу
workbook.close()
if __name__ == "__main__":
# Получаем аргументы командной строки
if len(sys.argv) == 4:
build_report(sys.argv[1], sys.argv[2], sys.argv[3])
Теперь рассмотрим код на стороне 1С, который выгружает данные во временные файлы, запускает этот скрипт и дожидается его завершения:
// 1. Формируем структуру данных для выгрузки
ДанныеПродаж = Новый Массив;
// Наполняем массив структурами (данные из вашей выборки/запроса)
НоваяСтрока = Новый Структура("Item, Qty, Sum", "Товар А", 10, 1500);
ДанныеПродаж.Добавить(НоваяСтрока);
ДанныеЗакупок = Новый Массив;
НоваяСтрокаЗакупки = Новый Структура("Item, Qty, Sum", "Сырье Б", 100, 8000);
ДанныеЗакупок.Добавить(НоваяСтрокаЗакупки);
// 2. Записываем данные в JSON-файлы во временную директорию Linux
ПутьПродажиJSON = "/tmp/sales_" + УникальныйИдентификатор() + ".json";
ПутьЗакупкиJSON = "/tmp/purch_" + УникальныйИдентификатор() + ".json";
ПутьИтоговыйXLSX = "/tmp/FinalReport.xlsx";
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ПутьПродажиJSON, "UTF-8");
ЗаписатьJSON(ЗаписьJSON, ДанныеПродаж);
ЗаписьJSON.Закрыть();
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ПутьЗакупкиJSON, "UTF-8");
ЗаписатьJSON(ЗаписьJSON, ДанныеЗакупок);
ЗаписьJSON.Закрыть();
// 3. Формируем команду запуска Python-скрипта
КомандаЗапуска = "python3 /opt/1c_scripts/create_excel.py "
+ ПутьПродажиJSON + " "
+ ПутьЗакупкиJSON + " "
+ ПутьИтоговыйXLSX;
// 4. Выполняем команду на сервере Linux синхронно (ожидая завершения)
КодВозврата = Неопределено;
ЗапуститьПриложение(КомандаЗапуска,, Истина, КодВозврата);
Если КодВозврата = 0 Тогда
ВызватьИсключение "Ошибка выполнения Python-скрипта формирования Excel!";
КонецЕсли;
// Дальнейшая обработка файла ПутьИтоговыйXLSX в 1С
Этот подход невероятно гибок и позволяет формировать отчеты абсолютно любого уровня сложности с минимальной нагрузкой на сам сервер 1С, перенося тяжелую математику и графическую отрисовку на плечи быстрого интерпретатора Python.
Если в вашей системе критически важна скорость генерации файлов (например, ежедневно формируются сотни тяжелых отчетов объемом в сотни тысяч строк), вызов внешних скриптов Python или использование штатных механизмов 1С может приводить к высокой загрузке процессора и задержкам.
В таких сценариях высокопроизводительным решением будет разработка или интеграция готовых внешних компонент Native API, написанных на C# (.NET Core) с использованием высокопроизводительных библиотек EPPlus или ClosedXML.
Скомпилированная под архитектуру Linux динамическая библиотека (с расширением .so) подключается в 1С стандартным методом ПодключитьВнешнююКомпоненту. Сборка многостраничного XLSX-архива происходит непосредственно в оперативной памяти сервера на уровне бинарного кода, что обеспечивает прирост скорости генерации документов в десятки раз по сравнению с классическими интерпретируемыми методами.
Когда требуется выполнить конвертацию существующих документов или произвести сложные манипуляции с листами, используя программные методы офисного пакета, на Linux-сервере можно запустить LibreOffice в скрытом фоновом режиме (так называемый headless-режим).
Для простых задач (например, конвертации готового MXL/PDF в XLSX) достаточно вызвать консольную утилиту:
libreoffice --headless --convert-to xlsx --outdir /tmp/ /tmp/source_doc.pdf
Для выполнения сложных алгоритмов построения таблиц используется технология UNO (Universal Network Objects). Скрипты на Python или Java могут подключаться к запущенному в фоне сервису LibreOffice по сети или локальному сокету, программно создавать вкладки, заполнять ячейки и форматировать документ так же, как это делалось через COM-объект в среде Windows. Однако из-за сложности настройки и высоких требований к оперативной памяти этот метод сейчас используется реже, уступая место специализированным библиотекам вроде openpyxl.
Выбор конкретного метода зависит от архитектуры вашей информационной системы и сложности финального отчета: