В макете ворда делаем определенный тег для форматированного документа, у меня это {v8 ФорматированныйДокумент}
Далее в коде после получения области
Область = УправлениеПечатью.ОбластьМакета(Макет, Области[ИмяМакета].ТекстФорматированногоДокумента);
Находим область и заменяем ее на наш сгенерированный xml код и присоединяем область.
ТекстОбласти = Область.Текст;
СтрокаПоискаБезТегов = "ФорматированныйДокумент";
СтрокаПоиска = "{v8 " + СтрокаПоискаБезТегов + "}";
НачалоОписания = СтрНайти(ТекстОбласти, СтрокаПоиска);
Описание = ЭтотОбъект.Описание;
НомерКартинки = 0;
Пока НачалоОписания <> 0 Цикл
ЗаменаОписанияНаХМЛ(НачалоОписания, ТекстОбласти, СтрокаПоиска, СтрокаПоискаБезТегов,
Описание, ДанныеОбъекта, НомерКартинки);
КонецЦикла;
Область.Текст = ТекстОбласти;
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта);
Процедура ЗаменаОписанияНаХМЛ(НачалоОписания, ТекстОбласти, СтрокаПоиска, СтрокаПоискаБезТегов, Описание, ДанныеОбъекта, НомерКартинки)
ТекстХМЛ = "";
ТекстИзменение = ТекстОбласти;
НачалоТекстаЗамены = СтрНайти(ТекстИзменение, "<w:p ", НаправлениеПоиска.СКонца, НачалоОписания);
КонецТекстаЗамены = СтрНайти(ТекстИзменение, "</w:p>", НаправлениеПоиска.СНачала, НачалоОписания);
Длина = КонецТекстаЗамены - НачалоТекстаЗамены;
ТекстЗамены = Сред(ТекстИзменение, НачалоТекстаЗамены, Длина + 6);
КонецПараграфа = СтрНайти(ТекстЗамены, ">");
Параграф = Лев(ТекстЗамены, КонецПараграфа);
НачалоСвойстваРаздела = СтрНайти(ТекстИзменение, "<w:pPr>", НаправлениеПоиска.СКонца);
СвойстваРаздела = Сред(ТекстИзменение, НачалоСвойстваРаздела);
КонецСвойстваРаздела = СтрНайти(СвойстваРаздела, "</w:pPr>");
СвойстваРаздела = Лев(СвойстваРаздела, КонецСвойстваРаздела + 7);
ЗапускТекста = "<w:r>";
Текст = "<w:t>";
Для каждого ПараграфФорматированногоДокумента из Описание.Элементы Цикл
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, Параграф);
ТекущееСвойствоРаздела = СвойстваРаздела;
Выравнивание = ПараграфФорматированногоДокумента.ГоризонтальноеПоложение;
Если Выравнивание <> ГоризонтальноеПоложение.Авто Тогда
Центр = "center";
Лево = "left";
Право = "right";
ПоШирине = "both";
Если Выравнивание = ГоризонтальноеПоложение.Лево Тогда
ТекущиеВырванивание = Лево;
КонецЕсли;
Если Выравнивание = ГоризонтальноеПоложение.Право Тогда
ТекущиеВырванивание = Право;
КонецЕсли;
Если Выравнивание = ГоризонтальноеПоложение.Центр Тогда
ТекущиеВырванивание = Центр;
КонецЕсли;
Если Выравнивание = ГоризонтальноеПоложение.ПоШирине Тогда
ТекущиеВырванивание = ПоШирине;
КонецЕсли;
НачалоСвойстваРаздела = СтрНайти(ТекущееСвойствоРаздела, "<w:jc w:val=""", НаправлениеПоиска.СКонца);
Если НачалоСвойстваРаздела <> 0 Тогда
ВыравниваниеСвойства = Сред(ТекущееСвойствоРаздела, НачалоСвойстваРаздела + 13);
КонецСвойстваРаздела = СтрНайти(ВыравниваниеСвойства, """/>");
ВыравниваниеСвойства = Лев(ВыравниваниеСвойства, КонецСвойстваРаздела - 1);
ТекущееСвойствоРаздела = СтрЗаменить(ТекущееСвойствоРаздела, ВыравниваниеСвойства, ТекущиеВырванивание);
Иначе
ВыравниваниеНовое = СтрШаблон("<w:jc w:val=""%1""/>", ТекущиеВырванивание);
ТекущееСвойствоРаздела = СтрЗаменить(ТекущееСвойствоРаздела, "<w:pPr>", "<w:pPr>" + ВыравниваниеНовое);
КонецЕсли;
КонецЕсли;
Если ПараграфФорматированногоДокумента.ТипПараграфа = ТипПараграфа.МаркированныйСписок Тогда
НумерованныйСписок = "<w:pPr><w:numPr><w:ilvl w:val=""0""/><w:numId w:val=""1""/></w:numPr>";
ТекущееСвойствоРаздела = СтрЗаменить(ТекущееСвойствоРаздела, "<w:pPr>", НумерованныйСписок);
ИначеЕсли ПараграфФорматированногоДокумента.ТипПараграфа = ТипПараграфа.НумерованныйСписок Тогда
НумерованныйСписок = "<w:pPr><w:numPr><w:ilvl w:val=""0""/><w:numId w:val=""2""/></w:numPr>";
ТекущееСвойствоРаздела = СтрЗаменить(ТекущееСвойствоРаздела, "<w:pPr>", НумерованныйСписок);
КонецЕсли;
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, ТекущееСвойствоРаздела);
Для каждого ЭлементыПараграфа Из ПараграфФорматированногоДокумента.Элементы Цикл
ТипТексФД = Тип("ТекстФорматированногоДокумента");
ТипКартинкаФД = Тип("КартинкаФорматированногоДокумента");
ТипПереводСтрокиФД = Тип("ПереводСтрокиФорматированногоДокумента");
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, ЗапускТекста);
Если ТипЗнч(ЭлементыПараграфа) = ТипТексФД Тогда
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, "<w:rPr>");
Шрифт = ЭлементыПараграфа.Шрифт;
ЦветТекста = ЭлементыПараграфа.ЦветТекста;
ЦветФона = ЭлементыПараграфа.ЦветФона;
Если ЦветТекста <> Новый Цвет() Тогда
РГБЦвет = ЦветТекста.ПолучитьАбсолютный();
Зеленый = РГБЦвет.Зеленый;
Красный = РГБЦвет.Красный;
Синий = РГБЦвет.Синий;
ХЕКСЦВЕТ = "#" + Сред(DecToAny(ПобитовоеИли(ПобитовоеИли(ПобитовоеИли(Синий, ПобитовыйСдвигВлево(Зеленый, 8)), ПобитовыйСдвигВлево(Красный, 16)), ПобитовыйСдвигВлево(1, 24)), 16), 2);
СтрокаТега = СтрШаблон("<w:color w:val=""%1""/>", ХЕКСЦВЕТ);
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, СтрокаТега);
КонецЕсли;
Если ЦветФона <> Новый Цвет() Тогда
РГБЦвет = ЦветФона.ПолучитьАбсолютный();
Зеленый = РГБЦвет.Зеленый;
Красный = РГБЦвет.Красный;
Синий = РГБЦвет.Синий;
ХЕКСЦВЕТ = "#" + Сред(DecToAny(ПобитовоеИли(ПобитовоеИли(ПобитовоеИли(Синий, ПобитовыйСдвигВлево(Зеленый, 8)), ПобитовыйСдвигВлево(Красный, 16)), ПобитовыйСдвигВлево(1, 24)), 16), 2);
СтрокаТега = СтрШаблон("<w:shd w:val=""clear"" w:color=""auto"" w:fill=""%1""/>", ХЕКСЦВЕТ);
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, СтрокаТега);
КонецЕсли;
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, "<w:rFonts w:ascii=""Times New Roman"" w:hAnsi=""Times New Roman"" w:cs=""Times New Roman""/>");
Если Шрифт.Полужирный <> Неопределено И Шрифт.Полужирный Тогда
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, "<w:b/>");
КонецЕсли;
Если Шрифт.Наклонный <> Неопределено И Шрифт.Наклонный Тогда
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, "<w:i/>");
КонецЕсли;
Если Шрифт.Подчеркивание <> Неопределено И Шрифт.Подчеркивание Тогда
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, "<w:u w:val=""single""/>");
КонецЕсли;
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, "</w:rPr>");
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, Текст + ЭлементыПараграфа.Текст +ЗакрывающийТег(Текст));
КонецЕсли;
Если ТипЗнч(ЭлементыПараграфа) = ТипКартинкаФД Тогда
СтруктураКартинки = Новый Структура("АдресКартинки");
НомерКартинки = НомерКартинки + 1;
Если ТипЗнч(ЭлементыПараграфа.Картинка) = Тип("Картинка") Тогда
КартинкаДвоичныеДанные = ЭлементыПараграфа.Картинка.ПолучитьДвоичныеДанные();
ИначеЕсли СтрНайти(ЭлементыПараграфа.Картинка, "https://") Тогда
АдресФайла = ЭлементыПараграфа.Картинка;
Защита = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
СтруктураУРИ = ОбщегоНазначенияКлиентСервер.СтруктураURI(АдресФайла);
Попытка
Соединение = Новый HTTPСоединение(СтруктураУРИ.ИмяСервера, , , , , , Защита);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Запрос = Новый HTTPЗапрос(СтруктураУРИ.ПутьНаСервере);
Ответ = ОтправитьЗапрос(Соединение, Запрос);
Если Ответ.КодСостояния = 200 Тогда
//Как то обрабатываем результат
КартинкаДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
//АдресХранилища = ПоместитьВоВременноеХранилище(ДД, Новый УникальныйИдентификатор);
Иначе
КартинкаДвоичныеДанные = ЭлементыПараграфа.Картинка;
КонецЕсли;
Иначе
//Если ЭлементыПараграфа.Высота > 0 И ЭлементыПараграфа.Ширина > 0 Тогда
// Высота = ЭлементыПараграфа.Высота/4;
// Ширина = ЭлементыПараграфа.Ширина/4;
// //КоэффициентПересчета = 914400/2.54/10*1000
// Если Ширина > 160 Тогда
// СтруктураКартинки.Вставить("Ширина", 160);
// СтруктураКартинки.Вставить("Высота", Высота/(Ширина/160));
// Иначе
// СтруктураКартинки.Вставить("Ширина", Ширина);
// СтруктураКартинки.Вставить("Высота", Высота);
// КонецЕсли;
//КонецЕсли;
СтрокаКартинка = ЭлементыПараграфа.Картинка;
СтрокаКартинка = СтрЗаменить(СтрокаКартинка, "data:image/png;base64,", "");
КартинкаДвоичныеДанные = Base64Значение(СтрокаКартинка);
КонецЕсли;
ТегКартинки = СтрШаблон("{v8 КартинкаФД_%1_Файл}", НомерКартинки);
КлючСтроки = СтрШаблон("КартинкаФД_%1_Файл", НомерКартинки);
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, Текст + ТегКартинки +ЗакрывающийТег(Текст));
СтруктураКартинки.АдресКартинки = ПоместитьВоВременноеХранилище(КартинкаДвоичныеДанные);
ДанныеОбъекта.Вставить(КлючСтроки, СтруктураКартинки);
КонецЕсли;
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, ЗакрывающийТег(ЗапускТекста));
КонецЦикла;
ТекстХМЛ = ДобавитьТекст(ТекстХМЛ, "</w:p>");
КонецЦикла;
ТекстОбласти = СтрЗаменить(ТекстОбласти, ТекстЗамены, ТекстХМЛ);
НачалоОписания = 0;
Для каждого ЭлементыСтруктуры Из ДанныеОбъекта Цикл
Если СтрНайти(ЭлементыСтруктуры.Ключ, "ФорматированныйДокумент") = 0 Тогда
Продолжить;
КонецЕсли;
Если СтрНайти(ТекстОбласти, ЭлементыСтруктуры.Ключ) <> 0 Тогда
НачалоОписания = СтрНайти(ТекстОбласти, ЭлементыСтруктуры.Ключ);
СтрокаПоиска = "{v8 " + ЭлементыСтруктуры.Ключ + "}";;
СтрокаПоискаБезТегов = ЭлементыСтруктуры.Ключ;
Описание = ЭлементыСтруктуры.Значение;
Возврат;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЗакрывающийТег(Тег)
Возврат СтрЗаменить(Тег, "<w", "</w")
КонецФункции // ()
Функция ДобавитьТекст(ТекстХМЛ, ДополнительныеДанные)
Возврат ТекстХМЛ + ДополнительныеДанные;
КонецФункции // ()
Функция DecToAny(Знач тЗначение, тОснование)
тРезультат = "";
Пока тЗначение > 0 Цикл
тРезультат = Сред("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", тЗначение%тОснование + 1, 1) + тРезультат;
тЗначение = Цел(тЗначение/тОснование) ;
КонецЦикла;
Возврат тРезультат;
КонецФункции
Функция ОтправитьЗапрос(Соединение, Запрос)
Ответ = Соединение.ВызватьHTTPМетод("GET", Запрос);
Если Ответ.КодСостояния = 200 Тогда
//Выходим из рекурсии
Возврат Ответ;
ИначеЕсли Ответ.КодСостояния > 300 И Ответ.КодСостояния < 400 Тогда
//Редирект
Ответ = ОбработатьРедирект(Соединение, Ответ);
ИначеЕсли Ответ.КодСостояния >= 400 Тогда
//Обработка ошибки
Возврат Ответ;
КонецЕсли;
Возврат Ответ;
КонецФункции
Функция ОбработатьРедирект(Соединение, Ответ)
В самом макете у меня добавлено два списка, это необходимо, чтобы у макета сформировались к ним описания в xml и в коде можно было бы применить форматирование списков.
Чтобы узнать, какой код необходим, надо разархивировать макет в формате docx, тогда в появившейся папке находим файл numbering.xml и оттуда берем необходимые параметры.
У меня получилось так:
В форматированный документ могут вставляться различные картинки и их формат может быть разным, поэтому был написан код под разные варианты.
Использовала следующие статьи и обработки на Инфостарте:
//infostart.ru/1c/tools/860960/
//infostart.ru/1c/tools/1324110/
//infostart.ru/1c/articles/1915944/
Тестировалось на "Библиотека стандартных подсистем", редакция 3.1 (3.1.9.104).
Проверено на следующих конфигурациях и релизах:
- 1С:ERP Управление предприятием 2, релизы 2.5.14.74