Задача: спарсить данные из таблицы, которая находится в файле формата docx средствами 1С
Решение: по сути своей файл формата docx является zip архивом, в котором находятся файлы формата xml и внешние ресурсы, типа картинок, стилей и т.п. Текстовое же содержимое находится непосредственно в файле document.xml. Его нужно лишь прочитать, найти в нём таблицу и распарсить данные.
Для начала загрузим файл на сервер, переименуем его в zip, и откроем его при помощи метода 1С «ЧтениеZipФайла», а найденный в архиве файл document.xml извлекем для дальнейшей обработки:
&НаКлиенте
Процедура ВыбратьФайлыИСделатьХорошо(Команда)
Режим = РежимДиалогаВыбораФайла.Открытие;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытияФайла.ПолноеИмяФайла = "";
Фильтр = НСтр("ru = 'Текст'; en = 'Text'")+ "(*.docx)|*.docx";
ДиалогОткрытияФайла.Фильтр = Фильтр;
ДиалогОткрытияФайла.МножественныйВыбор = ложь;
ДиалогОткрытияФайла.Заголовок = "Выберите файлы";
Если ДиалогОткрытияФайла.Выбрать() Тогда
МассивФайлов = ДиалогОткрытияФайла.ВыбранныеФайлы;
ФайлСМС="";
Для Каждого ИмяФайла Из МассивФайлов Цикл
ФайлСМС=ИмяФайла;
конеццикла;
если ФайлСМС<>"" тогда
АдресХранилищаФайла = "";
Состояние("Перемещаю файл на сервер");
ПоместитьФайл(АдресХранилищаФайла, ФайлСМС, , Ложь, ЭтаФорма.УникальныйИдентификатор);
Состояние("Обрабатывается файл "+ФайлСМС);
таблицы=ПреобразоватьФайлDocXВМассивТаблиц(АдресХранилищаФайла);
иначе
сообщить("Файл не выбран");
конецесли;
конецесли;
КонецПроцедуры
&НаСервере
Функция ПреобразоватьФайлDocXВМассивТаблиц(АдресХранилищаФайла)
ТЗ=Новый ТаблицаЗначений();
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилищаФайла);
ИмяВременногоФайлаСпр = ПолучитьИмяВременногоФайла("zip");
ДвоичныеДанные.Записать(ИмяВременногоФайлаСпр);
Архив = Новый ЧтениеZipФайла(ИмяВременногоФайлаСпр);
ИмяВременногоФайлаXML = ПолучитьИмяВременногоФайла("xml");
Для Каждого Элемент Из Архив.Элементы Цикл
если Элемент.Имя="document.xml" тогда
Архив.Извлечь(Элемент, КаталогВременныхФайлов(), РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
конецесли;
Конеццикла;
Архив.Закрыть();
....
Далее файл documnet.xml необходимо загрузить как XML и распарсить в структуру при помощи построителя DOM. После чего останется только найти таблицу по имени узла w:tbl и поместить содержимое в таблицу значений:
ФайлXML = Новый ЧтениеXML;
ФайлXML.ОткрытьФайл(КаталогВременныхФайлов()+"document.xml");
ПостроительDOMXML=Новый ПостроительDOM;
ДокументДом=ПостроительDOMXML.Прочитать(ФайлXML);
ПрочитаноСтрок=0;
для каждого document из ДокументДом.ДочерниеУзлы цикл
для каждого body из document.ДочерниеУзлы цикл
для каждого el из body.ДочерниеУзлы цикл
если el.ИмяУзла="w:tbl" тогда
для каждого tab_el из el.ДочерниеУзлы цикл
если tab_el.ИмяУзла="w:tr" тогда
если ПрочитаноСтрок=0 тогда
ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[1].ТекстовоеСодержимое));
ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[2].ТекстовоеСодержимое));
ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[3].ТекстовоеСодержимое));
ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[4].ТекстовоеСодержимое));
ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[5].ТекстовоеСодержимое));
ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[6].ТекстовоеСодержимое));
ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[7].ТекстовоеСодержимое));
ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[8].ТекстовоеСодержимое));
иначе
если tab_el.ДочерниеУзлы[1].ТекстовоеСодержимое="Всего:" тогда
прервать;
КонецЕсли;
если tab_el.ДочерниеУзлы[1].ТекстовоеСодержимое<>"1" тогда
если tab_el.ДочерниеУзлы[6].ТекстовоеСодержимое<>"" тогда
нс=ТЗ.Добавить();
нс[0]=tab_el.ДочерниеУзлы[1].ТекстовоеСодержимое;
нс[1]=tab_el.ДочерниеУзлы[2].ТекстовоеСодержимое;
нс[2]=tab_el.ДочерниеУзлы[3].ТекстовоеСодержимое;
нс[3]=tab_el.ДочерниеУзлы[4].ТекстовоеСодержимое;
нс[4]=tab_el.ДочерниеУзлы[5].ТекстовоеСодержимое;
нс[4]=СтрЗаменить(нс[4],",",".");
нс[4]=СтрЗаменить(нс[4]," ","");
если нс[4]="" тогда нс[4]="0";конецесли;
нс[4]=Число(Формат(нс[4],"ЧГ=0"));
нс[5]=tab_el.ДочерниеУзлы[6].ТекстовоеСодержимое;
нс[6]=tab_el.ДочерниеУзлы[7].ТекстовоеСодержимое;
нс[7]=tab_el.ДочерниеУзлы[8].ТекстовоеСодержимое;
нс[7]=СтрЗаменить(нс[7],",",".");
нс[7]=СтрЗаменить(нс[7]," ","");
если нс[7]="" тогда нс[7]="0";конецесли;
нс[7]=Число(Формат(нс[7],"ЧГ=0"));
конецесли;
конецесли;
конецесли;
ПрочитаноСтрок=ПрочитаноСтрок+1;
конецесли;
конеццикла;
если ПрочитаноСтрок>0 тогда прервать;конецесли;
конецесли;
если ПрочитаноСтрок>0 тогда прервать;конецесли;
конеццикла;
если ПрочитаноСтрок>0 тогда прервать;конецесли;
конеццикла;
если ПрочитаноСтрок>0 тогда прервать;конецесли;
конеццикла;
ФайлXML.Закрыть();
Возврат ТЗ;