gifts2017

Договора из Шаблона 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.Записать();
Попытка
УдалитьФайлы(ВременнаяПапка);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;

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

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

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

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Сергей Сытько (8SiriuS8) 15.11.13 22:40
(0) Да для фиксированного шаблона самая быстрая реализация. я бы добавил ещё код который упрощенно копи-пастом добавляет новую строку в простой таблице (Таблица без объединенных ячеек по вертикали)
2. Николай Шилкин (RayCon) 16.11.13 14:19
Файл не найден или был удален :(
3. BAZIL BAZIL (wbazil) 16.11.13 18:11
странно, в понедельник перезайлью т.к. файлы на работе
5. BAZIL BAZIL (wbazil) 18.11.13 10:54
6. rasswet (rasswet) 20.11.13 08:32
(1) поддерживаю.
(0)Можете добавить? раз уж вы в этой теме.
7. Василий Пупкин (Cyberhawk) 11.02.15 11:15
(1) или (6) - код по добавлению строк есть?
8. BAZIL BAZIL (wbazil) 12.02.15 11:52
(7) я добавление строк не делал, но в общем думаю надо брать простую таблицу выгружать в ХМЛ и смотреть как добавлять новую строку, если сами сделаете поделитесь в ЛС или прямо тут
9. Василий Пупкин (Cyberhawk) 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) 16.02.15 08:56
тоже встречался с этой проблемой, 100% ловиться когда при написании названия параметра переключать шрифт нажимать бекспейс
от решения не отказывался т.к. шаблоны делаются намного реже чем печатаются, да и пользователю сразу видно какой параметр ошибочно написан, имхо лучше поискать ошибочно написанный параметр чем воевать с зависшими вордами в терминале

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