Договора из Шаблона MS Word 2007+ без OLE

Опубликовал BAZIL BAZIL (wbazil) в раздел Программирование - Инструментарий

Обработка показывает, как можно создать шаблон в MS Word 2007+ и заполнить его данными из 1с, не используя технологию OLE

Обработка показывает как можно создать шаблон в MS Word 2007+ и заполнить его данными из 1с  не используя технологию OLE. Многие пользуются методом закладок, не считаю его удобным, поэтому хочу предложить идею которая использовалась мной давно в Delphi

Идея проста, сделать в тексте шаблона определённый текст который не будет повторяться и потом заменой заменить поля на нужные данные, поскольку файлы Word 2007+ это уже просто архивы ХМL, просто распаковываем делаем замену упаковываем обратно. На словах может немного сумбурно поэтому публикую сам код и пример в обработке.

поля могут быть отформатированы как нужно пользователю, т.е. можно использовать весь арсенал Word.

скорость работы высока,шаблон на 110 страниц который выложен в примере обрабатывается мение секунды.

 

Процедура кПолучитьДоговорНажатие(Элемент)
Режим = РежимДиалогаВыбораФайла.Открытие;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытияФайла.ПолноеИмяФайла = "";
Фильтр = "Word (*.docx)|*.docx";
ДиалогОткрытияФайла.Фильтр = Фильтр;
ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
ДиалогОткрытияФайла.Заголовок = "Выберите файл";

Если ДиалогОткрытияФайла.Выбрать() Тогда
ВыбФайл = Новый Файл(ДиалогОткрытияФайла.ПолноеИмяФайла);
ПутьИмяШаблона = ВыбФайл.ПолноеИмя;
ПутьИмяФайла = ПутьИмяШаблона + "_результат.docx";
Иначе
Текст = "ru = ""Файл(ы) не выбран!""; en = ""File(s) not selected!""";
Предупреждение(НСтр(Текст));
Возврат;
КонецЕсли;

СписокПараметров = Новый Структура;
СписокПараметров.Вставить("ААФИОАА","ИВАНОВ");
СписокПараметров.Вставить("ААНОМЕРАА","№456-АВ-789");
СписокПараметров.Вставить("ААДАТААА","16.01.2012");
Сообщить(ТекущаяДата()); 
псоПолучитьДоговор(ПутьИмяШаблона,ПутьИмяФайла,СписокПараметров);
Сообщить(ТекущаяДата());
КонецПроцедуры
//получает готовый договор с файла шаблона
//ПутьИмяШаблона - путь и имя файла шаблона docx
//ПутьИмяФайла - путь и имя файла куда сохранять готовый договор
//СписокПараметров - параметры и их значения для замены в договоре тип структура (Ключ,Значение)

Процедура псоПолучитьДоговор(ПутьИИмяШаблона,ПутьИИмяФайла,СписокПараметров);
Сейчас = ТекущаяДата();
ПутьИИмя = ПолучитьИмяВременногоФайла();
Путь = "";
Имя = "";
ПозСлэш = Найти(ПутьИИмя,"\");
Пока ПозСлэш > 0 Цикл
Путь = Путь+Сред(ПутьИИмя,1,ПозСлэш);
ПутьИИмя = Сред(ПутьИИмя,ПозСлэш+1);
ПозСлэш = Найти(ПутьИИмя,"\");
КонецЦикла;
Имя = ПутьИИмя;
Имя = Сред(Имя,1,СтрДлина(Имя)-4);
ВременнаяПапка = КаталогВременныхФайлов() + "1c" + Формат(Год("20031120"),"ЧГ=0") + Месяц(Сейчас) + День(Сейчас) + Час(Сейчас) + Минута(Сейчас) + Секунда(Сейчас) + Имя;

ЧтениеZIP = Новый ЧтениеZipФайла(ПутьИИмяШаблона);
ЧтениеZIP.ИзвлечьВсе(ВременнаяПапка, РежимВосстановленияПутейФайловZIP.Восстанавливать);
ЧтениеZIP.Закрыть();

Текст = Новый ЧтениеТекста(ВременнаяПапка + "\word\document.xml", КодировкаТекста.UTF8);
РезТекст = Новый ЗаписьТекста(ВременнаяПапка + "\word\document1.xml", КодировкаТекста.UTF8);

Стр = Текст.Прочитать();
Пока Стр <> Неопределено Цикл
Для каждого Элемент Из СписокПараметров Цикл
Стр = СтрЗаменить(Стр,Элемент.Ключ,Элемент.Значение);
КонецЦикла;
РезТекст.Записать(Стр);
Стр = Текст.Прочитать();
КонецЦикла;
Текст.Закрыть();
РезТекст.Закрыть();

Попытка
УдалитьФайлы(ВременнаяПапка + "\word\document.xml");
ПереместитьФайл(ВременнаяПапка + "\word\document1.xml",ВременнаяПапка + "\word\document.xml");
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;

ЗаписьZIP = Новый ЗаписьZipФайла(ПутьИИмяФайла);
ЗаписьZIP.Добавить(ВременнаяПапка + "\*.*", РежимСохраненияПутейZIP.СохранятьОтносительныеПути, РежимОбработкиПодкаталоговZIP.ОбрабатыватьРекурсивно);
ЗаписьZIP.Записать();
Попытка
УдалитьФайлы(ВременнаяПапка);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;

КонецПроцедуры

Скачать файлы

Наименование Файл Версия Размер
ОбработкаСПримеромИШаблоном
.zip 564,85Kb
18.11.13
50
.zip 564,85Kb 50 Скачать

См. также

Комментарии
1. Сергей Сытько (8SiriuS8) 114 15.11.13 22:40 Сейчас в теме
(0) Да для фиксированного шаблона самая быстрая реализация. я бы добавил ещё код который упрощенно копи-пастом добавляет новую строку в простой таблице (Таблица без объединенных ячеек по вертикали)
2. Николай Шилкин (RayCon) 638 16.11.13 14:19 Сейчас в теме
Файл не найден или был удален :(
3. BAZIL BAZIL (wbazil) 104 16.11.13 18:11 Сейчас в теме
странно, в понедельник перезайлью т.к. файлы на работе
5. BAZIL BAZIL (wbazil) 104 18.11.13 10:54 Сейчас в теме
6. rasswet (rasswet) 80 20.11.13 08:32 Сейчас в теме
(1) поддерживаю.
(0)Можете добавить? раз уж вы в этой теме.
7. Василий Пупкин (Cyberhawk) 96 11.02.15 11:15 Сейчас в теме
(1) или (6) - код по добавлению строк есть?
8. BAZIL BAZIL (wbazil) 104 12.02.15 11:52 Сейчас в теме
(7) я добавление строк не делал, но в общем думаю надо брать простую таблицу выгружать в ХМЛ и смотреть как добавлять новую строку, если сами сделаете поделитесь в ЛС или прямо тут
9. Василий Пупкин (Cyberhawk) 96 15.02.15 13:40 Сейчас в теме
К сожалению, пришлось отказаться от работы с Вордом без СОМ-модели, т.к. для замены текста (классическая задача по заполнению параметров печатных форм - договоров, например) через ковыряние в docx выяснилось, что текст иногда произвольным обрзом разделяется тегами w:r (параграфы, "run"); также положение курсора, начало-конец проверки орфографии и пунктуации и теги форматирования "вклиниваются" в куски текста внутри document.xml и делают замену текста делом практически нереальным.
Простой пример: пишу в Ворде текст (который должен заменяться потом программно в 1С) "[Договор.Номер]", в document.xml это превращается в
<w:t>Договор</w:t>
</w:r>
<w:r w:rsidR="00BD0530">
<w:rPr>
<w:rFonts w:ascii="Calibri" w:hAnsi="Calibri" w:cs="Calibri"/>
<w:sz w:val="22"/>
<w:szCs w:val="22"/>
</w:rPr>
<w:t>.</w:t>
</w:r>
<w:r w:rsidR="007F59CC">
<w:rPr>
<w:rFonts w:ascii="Calibri" w:hAnsi="Calibri" w:cs="Calibri"/>
<w:sz w:val="22"/>
<w:szCs w:val="22"/>
</w:rPr>
<w:t>НомерДоговора</w:t>)
...Показать Скрыть


Найденный способ обхода - вставлять текст-параметр в документ Ворд путем копирования цельного куска текста из внешнего редактора (из блокнота, например), для пользователя не под силу.
10. BAZIL BAZIL (wbazil) 104 16.02.15 08:56 Сейчас в теме
тоже встречался с этой проблемой, 100% ловиться когда при написании названия параметра переключать шрифт нажимать бекспейс
от решения не отказывался т.к. шаблоны делаются намного реже чем печатаются, да и пользователю сразу видно какой параметр ошибочно написан, имхо лучше поискать ошибочно написанный параметр чем воевать с зависшими вордами в терминале

ЗЫ. поэтому параметры в примере и обрамляются через АА...АА а не через {} или <>
11. Юрий Патласов (NoRazum) 18 01.04.15 20:27 Сейчас в теме
сама идея великолепная.
сделал на ней выгрузку. Все отлично немного со заменой помучился, но стоит этого.
Даже колонтитулы можно менять
ПЛЮС.