При автоматизации документооборота часто возникает задача: предоставить пользователям возможность формировать печатные формы по настраиваемым шаблонам Microsoft Word и Microsoft Excel. При этом требуется подставлять реквизиты объекта, динамически выводить строки табличных частей, сохранять работоспособность расчетных формул в таблицах и возвращать отредактированный файл обратно в базу данных. Рассмотрим основные способы реализации этого механизма в платформе 1С:Предприятие 8.3.
Классический подход заключается в создании файла-шаблона, в котором ключевые места заполнения помечаются специальными строковыми маркерами (например, [НомерДокумента], [Контрагент] или [BOX_Флаг] для чекбоксов). Программа считывает двоичные данные бланка, сохраняет их во временный файл и через COM-объект производит пакетный поиск и замену маркеров на фактические значения.
Рассмотрим пример кода для заполнения документа Microsoft Word, где также обрабатываются специальные символы для установки флажков (шрифт Wingdings):
ИмяВременногоФайла = ПолучитьИмяВременногоФайла(Расширение);
ДанныеФайла = ПолучитьДанныеФайла(Бланк);
ДанныеФайла.Записать(ИмяВременногоФайла);
ФлагВключен = "ю";
ФлагВыключен = "o";
Шрифт = "Wingdings";
Word = Новый COMОбъект("Word.Application");
Word.Documents.Open(ИмяВременногоФайла);
ДокументWord = Word.ActiveDocument();
Замена = ДокументWord.Content.Find;
Для Каждого ЭлементСтруктуры Из ЗначенияПолей Цикл
Ключ = "[" + ЭлементСтруктуры.Ключ + "]";
Значение = ЭлементСтруктуры.Значение;
ЭтоЧекБокс = Лев(Ключ, 5) = "[BOX_";
Если ЭтоЧекБокс Тогда
Флаг = ?(Значение = Истина, ФлагВключен, ФлагВыключен);
Если Замена.Execute(Ключ) Тогда
Замена.Replacement.Font.Name = Шрифт;
Замена.Execute(Ключ, Ложь, Истина, Ложь,,, Истина,, Истина, Флаг, 2);
КонецЕсли;
Иначе
Замена.Execute(Ключ, Ложь, Истина, Ложь,,, Истина,, Ложь, Значение, 2);
КонецЕсли;
КонецЦикла;
ДокументWord.Save();
ДокументWord.Close();
Теперь разберем аналогичный пример для книги Microsoft Excel, где поиск и замена осуществляются в пределах рабочего листа:
Excel = Новый COMОбъект("Excel.Application");
Книга = Excel.Workbooks.Open(ИмяВременногоФайла);
Лист = Книга.WorkSheets(1);
Для Каждого ЭлементСтруктуры Из ЗначенияПолей Цикл
Ключ = "[" + ЭлементСтруктуры.Ключ + "]";
Значение = ЭлементСтруктуры.Значение;
ЧекБокс = Лев(Ключ, 5) = "[BOX_";
Замена = Лист.UsedRange.Find(Ключ);
Если Замена <> Неопределено Тогда
Если ЧекБокс Тогда
Флаг = ?(Значение = Истина, ФлагВключен, ФлагВыключен);
Замена.Application.ReplaceFormat.Font.Name = Шрифт;
Замена.Replace(Ключ, Флаг,,, Ложь, Ложь, Ложь, Истина);
Иначе
Замена.Replace(Ключ, Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Книга.Save();
Excel.Quit();
Проанализируем типичные сложности при выводе табличных частей переменной длины в Excel-шаблоны:
СУММ(C5:C10)), простая перезапись значений в фиксированные ячейки не увеличивает размер диапазона при добавлении новых строк. Для корректного расширения формул необходимо вызывать метод вставки строк со сдвигом вниз: Лист.Rows(НомерСтроки).EntireRow.Insert(). В этом случае Excel автоматически корректирует координаты формул.Names в Excel). Присвоение имен ячейкам (например, НомерДоговора, СуммаДокумента) защищает структуру шаблона от случайного удаления маркеров пользователем при ручной корректировке макета.Выясним основные риски и ограничения COM-соединений, которые важно учитывать при проектировании архитектуры:
Word.Application и Excel.Application работают исключительно в операционных системах семейства Windows. При работе на сервере под управлением Linux, в веб-клиенте или мобильном приложении создание COM-объекта завершится критической ошибкой.excel.exe или winword.exe в памяти, блокировке временных файлов и утечкам ресурсов.Рассмотрим более современные и надежные варианты решения задачи:
Макет создается средствами 1С (тип «Табличный документ»). В ячейках можно задавать формулы, выравнивание, шрифты и границы. Данные заполняются стандартным программным методом вывода областей (Вывести(), Присоединить()). Готовый результат сохраняется в формат XLSX методом ТабличныйДокумент.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX). При такой выгрузке формулы и форматирование полностью переносятся в файл.
Современные файлы офисных форматов представляют собой ZIP-архивы, содержащие XML-файлы. С помощью объектов ЧтениеZipФайла и ЗаписьZipФайла можно распаковать архив, заменить нужные маркеры в XML-файлах документа через ЧтениеXML / ЗаписьXML или DOMДокумент, и упаковать файл обратно. Этот метод работает на любых операционных системах, не требует установленного пакета Office и выполняется значительно быстрее COM-вызовов.
В типовых конфигурациях 1С (например, 1С:Бухгалтерия, 1С:Документооборот) реализована встроенная подсистема печати по шаблонам Microsoft Word и OpenOffice с поддержкой управляющих конструкций вида {/v8 Область.Параметр}.
Для реализации сценария «открыть в Excel / Word, дать пользователю внести правки и сохранить результат в базу» разберем пошаговую схему взаимодействия:
Пользователь вносит корректировки в Excel/Word, нажимает «Сохранить» и закрывает офисную программу. Возврат данных в 1С можно организовать двумя способами: по нажатию кнопки «Завершить редактирование» в форме 1С (проверяется факт изменения файла по хэш-сумме или дате изменения и файл загружается обратно в хранилище значений) либо через периодический опрос доступности файла обработчиком ожидания.