Дисклеймер. Предыдущая версия этой статьи описывала формирование Word документов средствами БСП на стороне клиента. В новых же версиях БСП (в статье приводится пример на конфигурации с БСП 3.1.9.232) этот подход уже считается устаревшим, поэтому данная статья и все приведенные в ней примеры также были переработаны, чтобы соответствовать новым стандартам.
Начинаем с того, что создаем новую внешнюю обработку, в модуле объекта которой прописываем стандартную экспортную функцию "СведенияОВнешнейОбработке".
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
ПараметрыРегистрации.Вставить("Версия", "0.1");
ПараметрыРегистрации.Наименование = НСтр("ru = 'Внешняя печатная форма Word'");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru = 'Внешняя печатная форма Word'");
НоваяКоманда.Идентификатор = "ВнешняяПечатнаяФормаWord";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
Возврат ПараметрыРегистрации;
КонецФункции
Теперь первое, что нам нужно будет сделать, это подготовить шаблон Word документа. Этот процесс напоминает тот, который мы делали бы, если бы формировали обычную печатную форму - нам нужно выделить в нашей печатной форме различные области, такие как "Шапка", "Строка" и "Подвал", а внутри каждой из этих областей у нас будет содержаться некий текст с параметрами к подстановке.
В БСП заложен функционал, который позволяет решить эти задачи довольно легко и быстро.
Начнем с выделения областей. Для этого в БСП используется подход, напоминающий открывающиеся/закрывающиеся теги HTML или XML. В нашем документе Word нам нужно будет обрамить наши области специальными тегами, которые будут выглядеть следующим образом:
{v8 Область.ИмяМоейОбласти}
...
{/v8 Область.ИмяМоейОбласти}
В Word это будет выглядеть примерно так:
Эти теги позволят нам обращаться к этим областям позже в коде, но при выводе Word документа они, разумеется, будут удалены.
Теперь перейдем к параметрам печатной формы. Тут все еще проще. Параметр в Word документе должен иметь следующий вид:
{v8 ИмяПараметра}
После того как наш шаблон будет полностью готов, мы должны будем загрузить его в виде макета двоичных данных в нашу обработку:
Теперь в модуле объекта нашей обработки пропишем стандартную для внешних печатных форм процедуру "Печать":
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ВнешняяПечатнаяФормаWord") Тогда
СформироватьДокументWord(КоллекцияПечатныхФорм, МассивОбъектов);
КонецЕсли;
КонецПроцедуры
Вся же основная логика работы с Word документом - его объявление, определение и вывод областей, а также подстановка параметров - будет осуществлена в процедуре "СформироватьДокументWord".
Процедура СформироватьДокументWord(КоллекцияПечатныхФорм, МассивОбъектов) Экспорт
Если МассивОбъектов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Ссылка = МассивОбъектов[0];
ТипМакета = "DOC"; // Эта переменная уже устарела, и необходимость ее использования отпадет в новых версиях БСП, однако пока (БСП 3.1.9.232) она все еще нужна.
// Получаем структуру со сведениями о нашей печатной форме из коллекции печатных форм. В эту же структуру позже будет помещен сформированный нами документ Word.
ПечатнаяФорма = УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, "ВнешняяПечатнаяФормаWord");
ПечатнаяФорма.ТабличныйДокумент = Новый ТабличныйДокумент;
// Инициализируем макет документа Word на основании подготовленного заранее шаблона.
ДвоичныеДанныеМакета = ПолучитьМакет("ПФ_DOC_Макет");
СсылкаНаМакет = УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента(ДвоичныеДанныеМакета, ТипМакета, "ВнешняяПечатнаяФормаWord");
// Инициализируем печатную форму Word (docx), используя сформированный на прошлом этапе макет.
ПечатнаяФормаWord = УправлениеПечатью.ИнициализироватьПечатнуюФорму(ТипМакета, СсылкаНаМакет.НастройкиСтраницыМакета, СсылкаНаМакет);
// Подготовим параметры нашей печатной формы.
СтруктураПараметров = ПолучитьТабличнуюЧастьДокумента(Ссылка);
// Приступаем к заполнению нашего документа. Начинаем с объявления областей.
СтруктураОбластей = Новый Структура;
УправлениеПечатью.ДобавитьОписаниеОбласти(СтруктураОбластей, "Заголовок", "Общая");
УправлениеПечатью.ДобавитьОписаниеОбласти(СтруктураОбластей, "Данные", "СтрокаТаблицы");
УправлениеПечатью.ДобавитьОписаниеОбласти(СтруктураОбластей, "Подвал", "Общая");
// Получение областей, заполнение их параметров и вывод на документ Word.
// 1. Вывод заголовка документа.
ОбластьМакета = УправлениеПечатью.ОбластьМакета(СсылкаНаМакет, СтруктураОбластей.Заголовок);
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФормаWord, ОбластьМакета, СтруктураПараметров.ПараметрыШапки);
// 2. Вывод табличной части.
ОбластьМакета = УправлениеПечатью.ОбластьМакета(СсылкаНаМакет, СтруктураОбластей.Данные);
УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию(ПечатнаяФормаWord, ОбластьМакета, СтруктураПараметров.МассивТоваров);
// 3. Вывод подвала документа.
ОбластьМакета = УправлениеПечатью.ОбластьМакета(СсылкаНаМакет, СтруктураОбластей.Подвал);
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФормаWord, ОбластьМакета, Новый Структура);
// Формируем итоговый документ Word и помещаем его во временное хранилище, которое позже передаем структуре "ПечатнаяФорма".
АдресХранилищаОфисныйДокумент = УправлениеПечатью.СформироватьДокумент(ПечатнаяФормаWord);
// Очищаем ссылки - это необходимо для удаления временных файлов, созданных за кадром на предыдущих этапах.
УправлениеПечатью.ОчиститьСсылки(ПечатнаяФормаWord, Ложь);
УправлениеПечатью.ОчиститьСсылки(СсылкаНаМакет);
ОфисныеДокументы = Новый Соответствие;
ОфисныеДокументы.Вставить(АдресХранилищаОфисныйДокумент, НСтр("ru = 'Внешняя печатная форма Word'"));
ПечатнаяФорма.ОфисныеДокументы = ОфисныеДокументы;
КонецПроцедуры
Ниже пропишем содержание вспомогательной функций, используемой для получения параметров к подстановке:
Функция ПолучитьТабличнуюЧастьДокумента(Ссылка)
Запрос = Новый Запрос("ВЫБРАТЬ
| РеализацияТоваровУслуг.Номер КАК Номер
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура,
| Товары.КоличествоУпаковок КАК КоличествоУпаковок,
| Товары.Цена КАК Цена,
| Товары.СуммаСНДС КАК СуммаСНДС
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", Ссылка);
МассивРезультатов = Запрос.ВыполнитьПакет();
ВыборкаШапка = МассивРезультатов[0].Выбрать();
ВыборкаШапка.Следующий();
ПараметрыШапки = Новый Структура;
ПараметрыШапки.Вставить("Номер", "");
ЗаполнитьЗначенияСвойств(ПараметрыШапки, ВыборкаШапка);
ТаблицаТоваров = МассивРезультатов[1].Выгрузить();
МассивТоваров = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТаблицаТоваров);
Возврат Новый Структура("ПараметрыШапки, МассивТоваров", ПараметрыШапки, МассивТоваров);
КонецФункции
3. Заключение
Вот, собственно, и все. Согласитесь, совсем нетрудно. Для удобства к статье также прилагается файл внешней обработки, чтобы вы смогли сразу протестировать весь описанный в статье функционал.
Протестировано на конфигурации Управление торговлей, редакция 11.5.16.74 (БСП 3.1.9.232)