При автоматизации выгрузки отчетов нередко возникает задача скомпоновать несколько табличных документов в одну книгу .xlsx или добавить новый лист в существующий файл на сервере, где Microsoft Excel не установлен (например, на серверах под управлением Linux или Windows Server без офисного пакета). Платформенный объект ТабличныйДокумент при вызове метода Записать() перезаписывает файл и сохраняет строго один лист, поэтому стандартная прямая запись здесь не подходит. Разберем рабочие практические подходы к решению этой задачи.
Если задача заключается в том, чтобы сформировать многостраничный файл с нуля средствами самой 1С, наиболее простым и надежным решением является использование объекта ПакетОтображаемыхДокументов. Этот объект работает полностью автономно, не требует внешних библиотек и доступен на всех платформах.
Рассмотрим пример формирования книги с несколькими листами:
Пакет = Новый ПакетОтображаемыхДокументов;
// Помещаем сформированные табличные документы во временное хранилище
АдресЛиста1 = ПоместитьВоВременноеХранилище(ТабДокПродажи, Новый УникальныйИдентификатор);
АдресЛиста2 = ПоместитьВоВременноеХранилище(ТабДокОстатки, Новый УникальныйИдентификатор);
// Добавляем первый лист
Элемент1 = Пакет.Состав.Добавить();
Элемент1.Данные = АдресЛиста1;
Элемент1.Наименование = "Продажи";
// Добавляем второй лист
Элемент2 = Пакет.Состав.Добавить();
Элемент2.Данные = АдресЛиста2;
Элемент2.Наименование = "Складские остатки";
// Сохраняем готовую книгу в формате XLSX
Пакет.Записать(ПутьКФайлу, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
Важное ограничение: данный метод создает новый файл, но не позволяет открыть уже существующий файл с диска и дописать в него дополнительный лист.
Файл формата .xlsx представляет собой сжатый ZIP-контейнер, внутри которого находятся структурированные XML-файлы стандарта Office Open XML. Для модификации существующего файла можно распаковать архив, внести необходимые изменения и запаковать обратно, используя штатные объекты 1С ЧтениеZipФайла, ЗаписьZipФайла и ДокументDOM.
Разберем по шагам, какие именно файлы внутри архива требуется скорректировать для добавления нового листа:
xl/worksheets/ создается файл нового листа, например sheet2.xml, содержащий данные ячеек в теге <sheetData>.[Content_Types].xml добавляется узел Override, связывающий новый файл с типом application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml.xl/_rels/workbook.xml.rels создается элемент Relationship с типом схемы .../relationships/worksheet и ссылкой на относительный путь worksheets/sheet2.xml, где указывается уникальный идентификатор отношения (например, rId3).xl/workbook.xml внутри узла <sheets> добавляется элемент <sheet>, в котором прописываются имя листа, его числовой идентификатор sheetId и атрибут r:id, ссылающийся на созданную связь.Обратите внимание: если пропустить хотя бы одну из этих связей, офисный пакет при открытии сообщит о нарушении целостности книги и повреждении данных.
Если решение разворачивается в среде Windows, можно воспользоваться интерфейсом ADOX через провайдер Microsoft.ACE.OLEDB. В таком сценарии файл Excel рассматривается как база данных, а листы — как таблицы.
Посмотрим на пример добавления листа-таблицы через каталог ADOX:
Каталог = Новый COMОбъект("ADOX.Catalog");
Подключение = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;"";";
Подключение.Open(СтрокаПодключения);
Каталог.ActiveConnection = Подключение;
// Создаем новую таблицу (новый лист в Excel)
Таблица = Новый COMОбъект("ADOX.Table");
Таблица.Name = "НовыйЛист";
Таблица.Columns.Append("Код", 3); // 3 = adInteger
Таблица.Columns.Append("Номенклатура", 202, 150); // 202 = adVarWChar
Каталог.Tables.Append(Таблица);
Подключение.Close();
У этого метода есть существенные особенности, которые необходимо учитывать:
Microsoft.ACE.OLEDB, причем его разрядность (32 или 64 бита) должна строго совпадать с разрядностью службы сервера «1С:Предприятие».Если требуется модифицировать сложный существующий файл с сохранением макетов и оформлений на сервере без Excel, оптимальным подходом является использование консольных утилит через ЗапуститьПриложение():
load_workbook(), добавлять листы через create_sheet() и сохранять структуру без изменения исходного форматирования. Метод работает на любых операционных системах.ImportExcel, который взаимодействует со спецификацией OpenXML напрямую и не требует наличия установленного пакета Microsoft Office.