В процессе разработки отчетов в 1С:Предприятии 8.3 часто возникает потребность в их представлении в формате HTML. Это может быть обусловлено требованием к удобству просмотра, интеграцией с другими системами или специфическими дизайнерскими решениями. Рассмотрим, как мы можем формировать такие отчеты, разбирая основные подходы и наиболее эффективные практики.
Изначально автор темы попытался использовать механизм печати внешних обработок для вывода HTML-документа — для этого подойдёт конструктор макетов печатных форм и отчетов. Этот подход предполагает регистрацию обработки как печатной формы (в чем поможет отладка внешних печатных форм и обработок) и использование процедуры Печать с функцией УправлениеПечатью.ВывестиHTMLДокументВКоллекцию.
Рассмотрим структуру кода, который был представлен, чтобы понять его замысел:
Функция СведенияОВнешнейОбработке Экспорт
ПараметрыРегистрации = Новый Структура;
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Документ.Модернизация"); // Обработка связывается с документом
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "Отчёт по инвентаризация");
ПараметрыРегистрации.Вставить("БезопасныйРежим", ЛОЖЬ);
ПараметрыРегистрации.Вставить("Версия", "1.0");
ТаблицаКоманд = ПолучитьТаблицуКоманд;
ДобавитьКоманду(ТаблицаКоманд, "Отчёт по инвентаризации", "ОтчётПоИнвентаризации", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
// ... функции ПолучитьТаблицуКоманд и ДобавитьКоманду для регистрации команды печати ...
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Здесь происходит вызов функции для формирования HTML и его добавление в коллекцию
УправлениеПечатью.ВывестиHTMLДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ОтчётПоИнвентаризации",
"Отчёт по инвентаризации",
СформироватьПечатнуюФорму(МассивОбъектов[0], ОбъектыПечати));
КонецПроцедуры // Печать
Функция СформироватьПечатнуюФорму (СсылкаНаОбъект, ОбъектыПечати)
МакетОбработки = ПолучитьМакет("МакетОтчётПоИнвентаризации"); // Предполагается, что это HTML-макет
// Здесь должна быть логика получения данных и их вставки в макет,
// но в представленном коде она отсутствует, что является причиной 'пустой страницы'.
// Пример: Возврат МакетОбработки.ПолучитьТекст();
// или более сложная обработка:
// ТекстHTML = МакетОбработки.ПолучитьТекст();
// // Замена плейсхолдеров на данные
// ТекстHTML = СтрЗаменить(ТекстHTML, "[ИМЯ_ОБОРУДОВАНИЯ]", СсылкаНаОбъект.Наименование);
// Возврат ТекстHTML;
Возврат МакетОбработки.ПолучитьТекст(); // Для примера, чтобы не было пустой страницы
КонецФункции
Мы видим, что функция СформироватьПечатнуюФорму, которая должна возвращать HTML-текст, является неполной. Она только получает макет, но не возвращает его содержимое. Именно это является вероятной причиной того, что отчет выводится как пустая страница. Для корректной работы необходимо, чтобы функция СформироватьПечатнуюФорму возвращала строку с полным HTML-кодом, например, используя метод ПолучитьТекст() у объекта макета.
Один из самых надежных и часто используемых способов создания отчетов, которые могут быть сохранены в HTML, — это формирование отчета в виде объекта ТабличныйДокумент с последующим его программным сохранением. Этот подход предлагает хорошую совместимость и позволяет использовать все возможности платформы по построению отчетов.
Прежде всего, мы должны сформировать наш отчет как обычный ТабличныйДокумент. Мы можем использовать для этого систему компоновки данных (СКД), построитель отчетов или ручное формирование областей макета.
Рассмотрим простой пример создания табличного документа:
// Предположим, у нас есть процедура или функция, которая формирует ТабличныйДокумент
Функция СформироватьТабличныйДокумент(СсылкаНаОбъект)
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МакетОтчета"); // Макет табличного документа
// Получаем область макета для заголовка
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
ОбластьЗаголовок.Параметры.ТекстЗаголовка = "Отчет по оборудованию: " + СсылкаНаОбъект.Наименование;
ТабДок.Вывести(ОбластьЗаголовок);
// Получаем данные (это лишь пример, в реальном отчете будет запрос к БД)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Оборудование.Наименование,
| Оборудование.ИнвентарныйНомер,
| Оборудование.ДатаВводаВЭксплуатацию
|ИЗ
| Справочник.Оборудование КАК Оборудование
|ГДЕ
| Оборудование.Ссылка = &СсылкаНаОбъект";
Запрос.УстановитьПараметр("СсылкаНаОбъект", СсылкаНаОбъект);
Выборка = Запрос.Выполнить().Выбрать();
// Выводим шапку таблицы
ОбластьШапкаТаблицы = Макет.ПолучитьОбласть("ШапкаТаблицы");
ТабДок.Вывести(ОбластьШапкаТаблицы);
// Выводим строки таблицы
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Пока Выборка.Следующий() Цикл
ОбластьСтрока.Параметры.Заполнить(Выборка);
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
Возврат ТабДок;
КонецФункции
После формирования ТабличныйДокумент будет содержать всю необходимую информацию с заданным форматированием, включая QR и штрихкоды для печатных форм — поможет механизм добавления QR-кодов на печатные формы.
Когда ТабличныйДокумент готов, мы можем сохранить его в формате HTML с помощью метода Записать().
Рассмотрим, как это сделать:
// Вызов функции печати из внешней обработки
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Если МассивОбъектов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
СсылкаНаОбъект = МассивОбъектов[0]; // Берем первый объект для примера
ТабличныйДокументОтчета = СформироватьТабличныйДокумент(СсылкаНаОбъект);
ИмяФайла = ПолучитьИмяВременногоФайла(".html");
// Сохраняем ТабличныйДокумент в HTML
Попытка
ТабличныйДокументОтчета.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.HTML);
// Теперь, если необходимо, мы можем открыть этот файл
// или добавить его в коллекцию печатных форм для просмотра.
// Для демонстрации откроем файл:
ЗапуститьПриложение(ИмяФайла);
Исключение
Сообщить("Ошибка при сохранении отчета в HTML: " + ОписаниеОшибки());
КонецПопытки;
// Если нужно добавить в коллекцию печатных форм для вывода в 1С
// Область = ТабличныйДокументОтчета.Область();
// КоллекцияПечатныхФорм.Добавить(Область, "ОтчётПоИнвентаризации", "Отчёт по инвентаризации");
// Если мы хотим вывести в коллекцию HTML-документов:
// ТекстHTML = Новый ТекстовыйДокумент;
// ТекстHTML.Прочитать(ИмяФайла, КодировкаТекста.UTF8); // Или другая подходящая кодировка
// УправлениеПечатью.ВывестиHTMLДокументВКоллекцию(КоллекцияПечатныхФорм, "ОтчётПоИнвентаризации", "Отчёт по инвентаризации", ТекстHTML.ПолучитьТекст());
КонецПроцедуры
Метод ТабличныйДокумент.Записать() принимает в качестве второго параметра тип файла (обратите внимание на нюанс, если требуется вывод содержимого сгруппированных текстовых блоков). Мы можем использовать следующие значения:
ТипФайлаТабличногоДокумента.HTML: Сохраняет в общем формате HTML.ТипФайлаТабличногоДокумента.HTML3: Для совместимости со старыми программами просмотра.ТипФайлаТабличногоДокумента.HTML4: Последняя поддерживаемая версия.Важный момент: Если мы сталкиваемся с ошибками, связанными с доступом к файлу при использовании ТабДок.Записать(), особенно при сохранении на диск клиента в клиент-серверном варианте, может потребоваться выполнение этой строки кода на клиенте (используя директиву &НаКлиенте) или через файловые потоки.
Этот подход является очень гибким, так как позволяет использовать все привычные методы формирования отчетов в 1С, а затем просто конвертировать их в HTML. Однако следует учитывать, что при сохранении в HTML возможно неполное сохранение элементов оформления, так как ТабличныйДокумент имеет свои специфические особенности форматирования, которые могут не всегда точно транслироваться в HTML.
Для более продвинутых сценариев, особенно если мы используем конфигурации на базе Библиотеки стандартных подсистем (БСП), можно найти дополнительную гибкость. В БСП существует общий модуль РассылкаОтчетовПереопределяемый, который содержит процедуру ПередСохранениемТабличногоДокументаВФормат. Эта процедура позволяет нам определить свой обработчик для сохранения табличного документа в выбранном формате, переопределяя стандартные механизмы и добавляя собственную логику или специфические преобразования перед сохранением.
Если наша задача — не просто сохранить отчет в HTML, а отобразить его непосредственно на форме 1С, мы можем использовать элемент формы Поле HTML Документа. Этот элемент позволяет выводить HTML-содержимое прямо в форме, используя встроенный движок Webkit (аналогично Google Chrome). Этот способ особенно удобен для отображения различных инструкций, встроенной справки, путеводителей или любых других информационных страниц с форматированием и картинками.
Мы должны создать реквизит формы с типом Строка (неограниченной длины - Строка(0)), который будет хранить наш HTML-код. Затем мы размещаем на управляемой форме элемент Поле HTML Документа и связываем его с этим реквизитом.
Рассмотрим пример:
ТекстHTMLОтчета с типом Строка(0).Поле HTML Документа.Для отображения HTML-макета на форме мы просто присваиваем реквизиту формы, связанному с Полем HTML Документа, текст HTML-макета или любой сгенерированный HTML-код. Мы можем получить текст макета с помощью методов ПолучитьОбщийМакет("ИмяМакета").ПолучитьТекст() или ПолучитьМакет("ИмяМакета").ПолучитьТекст().
Посмотрим на пример в модуле формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем HTML-макет (предполагаем, что он уже создан в обработке)
МакетHTML = ПолучитьМакет("МакетОтчётПоИнвентаризации");
// Формируем HTML-текст. Здесь можно добавить данные из базы.
ТекстДляHTML = МакетHTML.ПолучитьТекст();
// Пример замены плейсхолдера
ТекстДляHTML = СтрЗаменить(ТекстДляHTML, "Тест
", "Отчет по оборудованию
Это сформированный HTML-отчет.
");
// Присваиваем HTML-текст реквизиту формы, который связан с Полем HTML Документа
ЭтотОбъект.ТекстHTMLОтчета = ТекстДляHTML;
КонецПроцедуры
Также мы можем использовать метод УстановитьHTML() непосредственно у объекта ПолеHTMLДокумента, если нам не нужен реквизит формы:
&НаКлиенте
Процедура ВывестиОтчетВПолеHTML(Команда)
// Получаем HTML-текст. Здесь может быть вызов серверной функции для формирования.
ТекстHTML = ПолучитьHTMLОтчетНаСервере(); // Пример вызова серверной функции
// Устанавливаем HTML-содержимое для поля
Элементы.ПолеHTMLДокумента1.УстановитьHTML(ТекстHTML);
КонецПроцедуры
&НаСервере
Функция ПолучитьHTMLОтчетНаСервере()
МакетHTML = ПолучитьМакет("МакетОтчётПоИнвентаризации");
// Здесь можно выполнить запросы к базе данных и сформировать полноценный HTML
ТекстДляHTML = МакетHTML.ПолучитьТекст();
ТекстДляHTML = СтрЗаменить(ТекстДляHTML, "Тест
", "Отчет по инвентаризации (пример)
Данные оборудования...
");
Возврат ТекстДляHTML;
КонецФункции
Этот способ позволяет создавать интерактивные элементы в HTML-документе, обрабатывать события, а также использовать JavaScript и CSS для создания динамичных форм — для такой задачи есть инструмент создания кастомных интерфейсов в 1С. Однако мы должны помнить, что Поле HTML Документа рекомендуется использовать для отображения информации, предназначенной в основном для просмотра. Для более сложных интерактивных элементов лучше применять штатные элементы управления 1С, поскольку платформа может не очень хорошо работать со сложными HTML-структурами, особенно если речь идет о высокоинтерактивных или объемных документах.
Независимо от выбранного способа вывода, для удобства хранения и редактирования HTML-кода мы можем создать в конфигурации новый макет, выбрав тип "HTML-документ". В редакторе макета мы можем напрямую писать HTML-теги и использовать CSS для стилизации. Эти макеты затем легко загружаются в Поле HTML Документа или используются для формирования строкового представления HTML-отчета.
Пример использования макета:
// В модуле объекта обработки или в модуле формы
МакетHTML = ПолучитьМакет("МойHTMLМакет"); // "МойHTMLМакет" - имя нашего макета типа "HTML-документ"
ТекстHTML = МакетHTML.ПолучитьТекст();
// Далее мы можем модифицировать ТекстHTML, вставляя данные из 1С
// и либо присваивать его Полю HTML Документа, либо записывать в файл.
Для более сложного и программно управляемого формирования HTML-документов в 1С можно использовать объектную модель DOM (Document Object Model) через объекты ДокументHTML, ЗаписьHTML и ЗаписьDOM. Этот подход предоставляет детальный контроль над структурой HTML, позволяя динамически создавать элементы, добавлять атрибуты и текст.
Рассмотрим упрощенный пример кода для такого подхода:
// Предполагаемая серверная функция
Функция СформироватьHTMLЧерезDOM(СсылкаНаОбъект)
Попытка
// Создаем новый HTML-документ
HTMLДокумент = Новый ДокументHTML;
// Получаем корневой элемент документа
ЭлементHTML = HTMLДокумент.documentElement;
// Создаем элемент
ЭлементHead = HTMLДокумент.СоздатьЭлемент("head");
ЭлементHTML.ДобавитьДочерний(ЭлементHead);
// Добавляем мета-тег для кодировки
МетаТег = HTMLДокумент.СоздатьЭлемент("meta");
МетаТег.УстановитьАтрибут("charset", "UTF-8");
ЭлементHead.ДобавитьДочерний(МетаТег);
// Добавляем заголовок страницы
ЭлементTitle = HTMLДокумент.СоздатьЭлемент("title");
ЭлементTitle.ТекстСодержимого = "Отчет по оборудованию";
ЭлементHead.ДобавитьДочерний(ЭлементTitle);
// Создаем элемент
ЭлементBody = HTMLДокумент.СоздатьЭлемент("body");
ЭлементHTML.ДобавитьДочерний(ЭлементBody);
// Добавляем заголовок отчета
ЭлементH1 = HTMLДокумент.СоздатьЭлемент("h1");
ЭлементH1.ТекстСодержимого = "Детальный отчет по оборудованию";
ЭлементBody.ДобавитьДочерний(ЭлементH1);
// Добавляем абзац с информацией об объекте
ЭлементP = HTMLДокумент.СоздатьЭлемент("p");
ЭлементP.ТекстСодержимого = "Наименование оборудования: " + СсылкаНаОбъект.Наименование;
ЭлементBody.ДобавитьДочерний(ЭлементP);
// Добавляем таблицу (простой пример)
ЭлементTable = HTMLДокумент.СоздатьЭлемент("table");
ЭлементTable.УстановитьАтрибут("border", "1");
ЭлементTable.УстановитьАтрибут("style", "width:100%; border-collapse: collapse;");
ЭлементBody.ДобавитьДочерний(ЭлементTable);
// Шапка таблицы
ЭлементTR = HTMLДокумент.СоздатьЭлемент("tr");
ЭлементTable.ДобавитьДочерний(ЭлементTR);
ЭлементTH1 = HTMLДокумент.СоздатьЭлемент("th");
ЭлементTH1.ТекстСодержимого = "Поле";
ЭлементTR.ДобавитьДочерний(ЭлементTH1);
ЭлементTH2 = HTMLДокумент.СоздатьЭлемент("th");
ЭлементTH2.ТекстСодержимого = "Значение";
ЭлементTR.ДобавитьДочерний(ЭлементTH2);
// Строки данных
Для Каждого КлючЗначение Из СсылкаНаОбъект.Метаданные().Реквизиты Цикл
ЭлементTRДанные = HTMLДокумент.СоздатьЭлемент("tr");
ЭлементTable.ДобавитьДочерний(ЭлементTRДанные);
ЭлементTD1 = HTMLДокумент.СоздатьЭлемент("td");
ЭлементTD1.ТекстСодержимого = КлючЗначение.Представление();
ЭлементTRДанные.ДобавитьДочерний(ЭлементTD1);
ЭлементTD2 = HTMLДокумент.СоздатьЭлемент("td");
ЗначениеРеквизита = СсылкаНаОбъект[КлючЗначение.Имя];
ЭлементTD2.ТекстСодержимого = Строка(ЗначениеРеквизита);
ЭлементTRДанные.ДобавитьДочерний(ЭлементTD2);
КонецЦикла;
// Записываем HTML-документ в строку
ЗаписьHTML = Новый ЗаписьHTML;
ЗаписьHTML.УстановитьСтроку();
ЗаписьDOM = Новый ЗаписьDOM;
ЗаписьDOM.Записать(HTMLДокумент, ЗаписьHTML);
Возврат ЗаписьHTML.Закрыть();
Исключение
Сообщить("Ошибка при формировании HTML через DOM: " + ОписаниеОшибки());
Возврат "";
КонецПопытки;
КонецФункции
// Пример вызова и использования в процедуре печати
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Если МассивОбъектов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
СсылкаНаОбъект = МассивОбъектов[0];
ТекстHTML = СформироватьHTMLЧерезDOM(СсылкаНаОбъект);
Если НЕ ПустаяСтрока(ТекстHTML) Тогда
УправлениеПечатью.ВывестиHTMLДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ОтчетЧерезДОМ",
"Отчет через DOM-модель",
ТекстHTML);
КонецЕсли;
КонецПроцедуры
Этот метод предоставляет максимальный контроль, но требует более детальной проработки кода для создания каждого элемента HTML. Он может быть полезен, когда нам нужно генерировать очень специфический или динамически изменяющийся HTML, который сложно описать в статических макетах.
При работе с HTML-документами в 1С мы можем использовать стандартные инструменты разработчика браузера (например, Chrome DevTools или Firefox Developer Tools). Если вы сохраняете HTML-файл на диск, откройте его в браузере и используйте эти инструменты для проверки верстки, стилей (CSS) и поведения (JavaScript), если он присутствует. Это значительно упростит поиск ошибок в HTML-коде, который формируется в 1С.
Мы рассмотрели несколько подходов к созданию и выводу HTML-отчетов в 1С:Предприятии 8.3. Выбор конкретного метода зависит от сложности требуемого HTML-документа, необходимости интерактивности и предпочтений в разработке:
ТабличныйДокумент, наиболее универсальным будет формирование ТабличногоДокумента и его последующее сохранение в HTML-файл.Поле HTML Документа, присваивая ему готовый HTML-текст (возможно, из макета).Всегда стоит помнить об ограничениях 1С при работе со сложными HTML-структурами в элементе Поле HTML Документа и при сохранении ТабличногоДокумента в HTML, так как не все тонкости форматирования могут быть идеально перенесены.