По этой теме есть публикация на ИТС Разработка печатных форм с использованием макетов в формате офисных документов Office Open XML , есть несколько статей на инфостарте- первая статья, вторая статья .
В статье на ИТС и в первой статье описывается создание печатной формы, но при этом для печатной формы используется метод менеджера объекта, что предполагает внесение изменения в конфигурацию или в расширение конфигурации.
В моей статье описывается, как это обойти и внести все нужные изменения во внешнюю обработку.
Сама печатная форма создается на клиентской стороне.
Шаг 1. Создание внешней обработки.
Создать внешнюю обработку, в модуле объекта обработки заполнить функцию СведенияОВнешнейОбработке.
Ниже пример из обработки к статье
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Справочник.ПодразделенияОрганизаций");
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "Договор коллективной материальной ответственности (в Word)");
ПараметрыРегистрации.Вставить("Версия", "1.1");
ПараметрыРегистрации.Вставить("БезопасныйРежим", ИСТИНА);
ПараметрыРегистрации.Вставить("Информация", "Договор коллективной материальной ответственности (в Word). Автор - Петрянкин В.Ф. ");
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд, "Договор коллективной материальной ответственности (в Word)", "Макет", "ВызовКлиентскогоМетода", Истина, "");
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
ПараметрыРегистрации.Вставить("БезопасныйРежим",Ложь);
Возврат ПараметрыРегистрации;
КонецФункции
Также у вас должен быть файл Word, который будет использоваться для формирования печатной формы. Поддерживаются формат как doc , так и docx .
Шаг 2. Создание макета.
Во внешней обработке надо создать новый макет . Тип макета- двоичные данные, имя макета- ПФ_DOC_МакетОтчета.
В файле Word , который будет загружен в этот макет обработки, надо выделить области .
Этих областей может быть три типа, про это есть описание на ИТС. Тип Общая- область , используемая один раз, СтрокаТаблицы — область для вывода табличной части.
Области выделяются "тегами": начало области {v8 Область.<Имя области>}, конец области {/v8 Область.<Имя области>}
Пример описания области .
{v8 Область.Заголовок} — Начало области с именем Заголовок, это обычный текст в файле, в печатной форме он отображаться не будет
… Здесь содержимое области
{/v8 Область.Заголовок}- Окончание этой области
В каждой области для параметров, которые будут замещаться нужным текстом создаются описания вида
{v8 НаименованиеОрганизации} — описание параметра НаименованиеОрганизации. Т.е. у параметров есть только открывающий тег и нет служебного слова Область.
Оформление областей можно посмотреть на ИТС и в обработке к этой статье.
После оформления областей этот документ надо загрузить в макет обработки.
Шаг 3. Создание функции подготовки данных для печати.
На ИТС и в демо-базе БСП эта функция располагается в менеджере объекта, для которого создается печатная форма.
Для внешней печатной формы эту функцию надо разместить в форме обработки — печатная форма создается на стороне клиента.
Ниже текст этой функции
// Подготавливает данные объекта к выводу на печать.
//
// Параметры:
// МассивДокументов - Массив - ссылки на объекты, для которых запрашиваются данные для печати;
// МассивИменМакетов - Массив - имена макетов, в которые подставляются данные для печати.
//
// Возвращаемое значение:
// Соответствие - коллекция ссылок на объекты и их данные:
// * Ключ - ЛюбаяСсылка - ссылка на объект информационной базы;
// * Значение - Структура - макет и данные:
// ** Ключ - Строка - имя макета,
// ** Значение - Структура - данные объекта.
&НаСервере
Функция ПолучитьДанныеПечати(Знач МассивДокументов, Знач МассивИменМакетов) Экспорт
ДанныеПоВсемОбъектам = Новый Соответствие;
Для Каждого ОбъектСсылка Из МассивДокументов Цикл
ДанныеОбъектаПоМакетам = Новый Соответствие;
Для Каждого ИмяМакета Из МассивИменМакетов Цикл
ДанныеОбъектаПоМакетам.Вставить(ИмяМакета, ПолучитьДанныеОбъекта(ОбъектСсылка));
КонецЦикла;
ДанныеПоВсемОбъектам.Вставить(ОбъектСсылка, ДанныеОбъектаПоМакетам);
КонецЦикла;
ОписаниеОбластей = Новый Соответствие;
ДвоичныеДанныеМакетов = Новый Соответствие;
ТипыМакетов = Новый Соответствие; // Для обратной совместимости.
Для Каждого ИмяМакета Из МассивИменМакетов Цикл
Если ИмяМакета = "МакетОтчета(Word)" Тогда
ДвоичныеДанныеМакета = РеквизитФормыВЗначение("Объект").ПолучитьМакет("ПФ_DOC_МакетОтчета");
ДвоичныеДанныеМакетов.Вставить(ИмяМакета, ДвоичныеДанныеМакета);
ТипыМакетов.Вставить(ИмяМакета, "DOC");
КонецЕсли;
ОписаниеОбластей.Вставить(ИмяМакета, ПолучитьОписаниеОбластейМакетаОфисногоДокумента());
КонецЦикла;
Макеты = Новый Структура;
Макеты.Вставить("ОписаниеОбластей", ОписаниеОбластей);
Макеты.Вставить("ТипыМакетов", ТипыМакетов); // Для обратной совместимости.
Макеты.Вставить("ДвоичныеДанныеМакетов", ДвоичныеДанныеМакетов);
Результат = Новый Структура;
Результат.Вставить("Данные", ДанныеПоВсемОбъектам);
Результат.Вставить("Макеты", Макеты);
Возврат Результат;
КонецФункции
Шаг 4. Создание служебных функций и процедуры
- функция ДанныеЗаполненияОтчета(СсылкаНаОбъект)
- функция ПолучитьОписаниеОбластейОфисногоДокумента()
- процедура ВыполнитьПечатьвWord(ДокументСсылка, МакетИДанныеОбъекта, ИмяМакета)
Эти две функции и процедура будут уникальными для конкретной печатной формы.
Прилагаемую к статье обработку можно использовать как шаблон, в котором для вашей конкретной печатной формы надо внести изменения.
Примеры функций
&НаСервере
Функция ДанныеЗаполненияОтчета(СсылкаНаСправочник)
ДанныеОбъекта = Новый Структура();
ДатаПечати=ТекущаяДата();
ДатаДокумента=Формат(ДатаПечати,"ДЛФ=DD");
ДанныеОбъекта.Вставить("ДатаДокумента",ДатаДокумента);
ОрганизацияПодразделения=СсылкаНаСправочник.Владелец;
ДанныеОбъекта.Вставить("НаименованиеОрганизации",ОрганизацияПодразделения.НаименованиеПолное);
...
Возврат ДанныеОбъекта;
КонецФункции
Вышеприведенная функция подставляет параметры ДатаДокумента и НаименованиеОрганизации .
В файле Word эти параметры оформлены следующим образом:
{v8 НаименованиеОрганизации}, в лице {v8 ДолжностьПодписанта} {v8 ФИОПодписанта}, действующего на основании {v8 ДокументПодписанта}, именуемое в дальнейшем “Работодатель”, с одной стороны и гр. {v8 ФИО}, именуемый (ая) в дальнейшем “Работник” с другой стороны, именуемые в дальнейшем “Стороны”, заключили в соответствии с Трудовым кодексом Российской Федерации настоящие дополнения
&НаСервере
Функция ПолучитьОписаниеОбластейМакетаОфисногоДокумента()
ОписаниеОбластей = Новый Структура;
УправлениеПечатью.ДобавитьОписаниеОбласти(ОписаниеОбластей, "Заголовок", "Общая");
УправлениеПечатью.ДобавитьОписаниеОбласти(ОписаниеОбластей, "ШапкаКоллектива", "Общая");
УправлениеПечатью.ДобавитьОписаниеОбласти(ОписаниеОбластей, "СтрокаТаблицы", "СтрокаТаблицы");
УправлениеПечатью.ДобавитьОписаниеОбласти(ОписаниеОбластей, "ПодвалКоллектива", "Общая");
Возврат ОписаниеОбластей;
КонецФункции
В этой функции описаны области в файле Word . Видно, что в этом файле выделено 4 области, три из которых вызываются один раз, а область СтрокаТаблицы отображает данные из табличной части.
Ниже процедура, которая выполняется на стороне клиента и выводит эти области
&НаКлиенте
Процедура ВыполнитьПечатьВWord(ДокументСсылка, МакетИДанныеОбъекта, ИмяМакета)
ТипМакета = МакетИДанныеОбъекта.Макеты.ТипыМакетов[ИмяМакета];
ДвоичныеДанныеМакетов = МакетИДанныеОбъекта.Макеты.ДвоичныеДанныеМакетов;
Области = МакетИДанныеОбъекта.Макеты.ОписаниеОбластей;
ДанныеОбъекта = МакетИДанныеОбъекта.Данные[ДокументСсылка][ИмяМакета];
Макет = УправлениеПечатьюКлиент.ИнициализироватьМакетОфисногоДокумента(ДвоичныеДанныеМакетов[ИмяМакета], ТипМакета, ИмяМакета);
Если Макет = Неопределено Тогда
Возврат;
КонецЕсли;
ЗакрытьОкноПечатнойФормы = Ложь;
Попытка
ПечатнаяФорма = УправлениеПечатьюКлиент.ИнициализироватьПечатнуюФорму(ТипМакета, Макет.НастройкиСтраницыМакета, Макет);
Если ПечатнаяФорма = Неопределено Тогда
УправлениеПечатьюКлиент.ОчиститьСсылки(Макет);
Возврат;
КонецЕсли;
// Вывод заголовка документа.
Область = УправлениеПечатьюКлиент.ОбластьМакета(Макет, Области[ИмяМакета]["Заголовок"]);
УправлениеПечатьюКлиент.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта, Ложь);
Область = УправлениеПечатьюКлиент.ОбластьМакета(Макет, Области[ИмяМакета]["ШапкаКоллектива"]);
УправлениеПечатьюКлиент.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта, Ложь);
Если ДанныеОбъекта.Свойство("СтрокаТаблицы_1") Тогда
Область = УправлениеПечатьюКлиент.ОбластьМакета(Макет, Области[ИмяМакета]["СтрокаТаблицы"]);
УправлениеПечатьюКлиент.ПрисоединитьИЗаполнитьКоллекцию(ПечатнаяФорма, Область, ДанныеОбъекта.СтрокаТаблицы_1, Ложь);
КонецЕсли;
Область = УправлениеПечатьюКлиент.ОбластьМакета(Макет, Области[ИмяМакета]["ПодвалКоллектива"]);
УправлениеПечатьюКлиент.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта, Ложь);
УправлениеПечатьюКлиент.ПоказатьДокумент(ПечатнаяФорма);
Исключение
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
ЗакрытьОкноПечатнойФормы = Истина;
Возврат;
КонецПопытки;
УправлениеПечатьюКлиент.ОчиститьСсылки(ПечатнаяФорма, ЗакрытьОкноПечатнойФормы);
УправлениеПечатьюКлиент.ОчиститьСсылки(Макет);
КонецПроцедуры
Обработка , прилагаемая к статье используется в конфигурации ЗУП 3.1.8.246 с версией подсистемы БСП 3.0.1.369
Вы можете использовать ее как шаблон для вашей печатной формы.
Для этого:
- Надо изменить функции и процедуру , которые описаны на шаге 4:
- функцию ДанныеЗаполненияОтчета(СсылкаНаОбъект)
- функцию ПолучитьОписаниеОбластейОфисногоДокумента()
- процедуру ВыполнитьПечатьвWord(ДокументСсылка, МакетИДанныеОбъекта, ИмяМакета)
- В вашем файле Word оформить области и загрузить в макет обработки
(0) | А в серверном варианте возможно сделать такую форму ?
Можно
(1) Возможно. Но не очень красиво это всё передаётся на клиента, либо я рукожоп. Идёшь из обработки на сервер, реквизит формы в значение получаешь объект обработки. Оттуда получаешь макет (в моем случае это active document). Потом его сохраняешь во временный файл, потом этот временный файл перегоняешь в двоичные данные, потом уже во временное хранилище. И потом из временного хранилища обратно на клиенте в файл и оттуда уже com-объект. Хз насколько это правильно, но у меня работает.
(2) а как вывести два разных нижних колонтитула? у меня два раздела, в шаблоне колонтитул указал только в одном, но он мне заполняет по всем разделам документа.
Несколько лет работаем по похожей обработке, но у нас терминальный сервер с установленным Ворд. 1С работает в обычном файловом режиме, платформа 64-bit, конфа отраслевая, поэтому нет смысла её описывать, но вроде на базе обычной бухгалтерии. Все работает нормально, кроме одной проблемы — АЦКИ долго… один договор в ВОРД может печататься около 1,5 минут, в Опен Офисе побыстрее, но он глючить начинает. Эта проблема давняя и известная, но ничего нового для решения найти не могу, можете подсказать?
Не понятно с областями:
Этих областей может быть три типа, про это есть описание на ИТС. Тип Общая- область , используемая один раз
и пример в коде:
УправлениеПечатью.ДобавитьОписаниеОбласти(ОписаниеОбластей, «Заголовок», «Общая»);
УправлениеПечатью.ДобавитьОписаниеОбласти(ОписаниеОбластей, «ШапкаКоллектива», «Общая»);
УправлениеПечатью.ДобавитьОписаниеОбласти(ОписаниеОбластей, «СтрокаТаблицы», «СтрокаТаблицы»);
УправлениеПечатью.ДобавитьОписаниеОбласти(ОписаниеОбластей, «ПодвалКоллектива», «Общая»);
Так всё же один или нет?
Разных областей с типом Общая м.б. сколько угодно.
Каждая такая область выводится в печатную форму один раз.
Где функция ПолучитьТаблицуКоманд(); ?
Где положено , там — в модуле объекта
Я так и не понял. Эта обработка в итоге работает в безопасном режиме или нет? В функции СведенияОВнешнейОбработке() сначала идёт установка параметра БезопасныйРежим = ИСТИНА, а потом установка этого же параметра в значение Ложь. Так что в итоге? Обработка работает в безопасном режиме или всё-таки нет?