Доброго времени суток.
Столкнулся, значит, с такой проблемой. Есть обработка в 1С 8.2 и туда надо запихнуть в автоматическом режиме кучу данных. Куча данных находилась в своей базе данных, в своей архитектуре и подключить базу к 1С или переформатировать таблицы не представлялось возможным. Единственный способ, как мне показалось, вывести таблицу на виртуальный принтер, а оттуда и плясать начнем.
Итак, имеем документ в формате *.xps, который нам дал заботливый виртуальный принтер:

Собственно, из этого всего, мне нужны только строчки самой работы, строчки подработ (начинаются со знака "-") и колонка нормы времени для каждой работы. Сначала я подумал, что формат XPS графический и придется полученный файл загонять в любую OCR программу, там распознавать таблицу и сохранять данные в формате Excel. Сначала так и сделалось, но есть огромные минусы:
— нет автоматизации процесса при конвертировании XPS -> 1C.
— OCR программы могут накосячить в распознавании текста.
— процесс конвертации занимает много времени.
Поэтому пришлось разбираться с форматом XPS напрямую.
Собственно, как оказывается, формат XPS — это обычный ZIP-файл. Вся информация там находится в виде XML. Картинки идут картинками, текст текстом. Но нам-то текст и нужен…
Внутри имеем такую картину:

Не буду вдаваться в подробности и содержание каждой папки – там все просто, если интересно, то можно полазить и самому. Меня конкретно интересует только один файл:
..\ Documents\1\FixedDocument.fdoc
Вот листинг этого файла:
Как видим, тут пути к файлам страниц документа.
Оформляем это все в код 1С:
Для начала разархивируем содержимое файла во временную папку:
Теперь в директории файла имеем все возможности для работы. Нас интересует, как писалось выше, список файлов со страницами. Перегружаем список в таблицу. Работаем с этим файлом как с обычным XML:
Все, имеем список файлов. Теперь приступаем к самим файлам. Файл страницы сам текстовый, но правила написания не XML. Структура блочная. Блоками отдельно пишется текстовая информация и графическая. Все блоки имеют координаты по оси Х и Y, для расположения на странице. Меня интересуют только текстовые блоки и их координаты, ну и их информация.
Блоки имеют начало и конец, понять где начало и конец просто: < />
В каждом блоке первое слово — его имя. Текстовые блоки имеют имя: Glyphs
Вот пример блока:
Меня интересуют тут только параметры:
— OriginX, для определения колонок.
— UnicodeString как само значение того, что содержится в строке.
Читать придется как обычный текстовый файл. Текстовые блоки все пишутся одной строкой. В 1С можно прочитать строку до символа перевода коретки:
А полученную строку проверяем на параметр, если начинается на Glyphs, то берем на проверку и анализ, если нет — читаем следующий.
Придется строку анализировать побуквенно и переписывать в структуру.
Собственно, по выполнении функции, имеем все для анализа. Имя параметра, его координаты, значение параметра. Блоки выводят текст в XPS сверху вниз и слева направо. По координатам Х можно определить колонки, по названию параметра можем проанализировать какая информация нам нужна, а какая нет. Дальше расписывать как оно все уходило в справочник 1С не буду — там и так все понятно. Главное, я получил ответ как быстро извлечь нужную информацию из «графического» файла.
Столкнулся, значит, с такой проблемой. Есть обработка в 1С 8.2 и туда надо запихнуть в автоматическом режиме кучу данных. Куча данных находилась в своей базе данных, в своей архитектуре и подключить базу к 1С или переформатировать таблицы не представлялось возможным. Единственный способ, как мне показалось, вывести таблицу на виртуальный принтер, а оттуда и плясать начнем.
Итак, имеем документ в формате *.xps, который нам дал заботливый виртуальный принтер:

Собственно, из этого всего, мне нужны только строчки самой работы, строчки подработ (начинаются со знака "-") и колонка нормы времени для каждой работы. Сначала я подумал, что формат XPS графический и придется полученный файл загонять в любую OCR программу, там распознавать таблицу и сохранять данные в формате Excel. Сначала так и сделалось, но есть огромные минусы:
— нет автоматизации процесса при конвертировании XPS -> 1C.
— OCR программы могут накосячить в распознавании текста.
— процесс конвертации занимает много времени.
Поэтому пришлось разбираться с форматом XPS напрямую.
Собственно, как оказывается, формат XPS — это обычный ZIP-файл. Вся информация там находится в виде XML. Картинки идут картинками, текст текстом. Но нам-то текст и нужен…
Внутри имеем такую картину:

Не буду вдаваться в подробности и содержание каждой папки – там все просто, если интересно, то можно полазить и самому. Меня конкретно интересует только один файл:
..\ Documents\1\FixedDocument.fdoc
Вот листинг этого файла:
<?xml version="1.0" encoding="UTF-8" ?> - <FixedDocument xmlns="http://schemas.microsoft.com/xps/2005/06"> <PageContent Source="/Documents/1/Pages/1.fpage" /> <PageContent Source="/Documents/1/Pages/2.fpage" /> <PageContent Source="/Documents/1/Pages/3.fpage" /> <PageContent Source="/Documents/1/Pages/4.fpage" /> </FixedDocument>
Как видим, тут пути к файлам страниц документа.
Оформляем это все в код 1С:
Процедура ОсновныеДействияФормыВСправочник(Кнопка) РежимДиалога = РежимДиалогаВыбораФайла.Открытие; ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалога); ДиалогВыбора.МножественныйВыбор = Истина; ДиалогВыбора.Фильтр = "XPS |*.xps"; Если ДиалогВыбора.Выбрать() Тогда Количество = ДиалогВыбора.ВыбранныеФайлы.Количество(); Для Стр = 0 по Количество - 1 Цикл ПолучитьДанныеХПС(ДиалогВыбора.ВыбранныеФайлы[Стр], ДиалогВыбора.Каталог); ПерегнатьВСправочник(); КонецЦикла; КонецЕсли; КонецПроцедуры
Для начала разархивируем содержимое файла во временную папку:
Процедура ПолучитьДанныеХПС (Файл, Каталог) КодМарки = СтрЗаменить(Файл, Каталог, ""); КодМарки = СтрЗаменить(КодМарки, ".xps", ""); СоздатьКаталог(Каталог + КодМарки); ЗИПФайл = Новый ЧтениеZipФайла(Файл); ЗИПФайл.ИзвлечьВсе(Каталог + КодМарки, РежимВосстановленияПутейФайловZIP.Восстанавливать); ЗИПФайл.Закрыть();
Теперь в директории файла имеем все возможности для работы. Нас интересует, как писалось выше, список файлов со страницами. Перегружаем список в таблицу. Работаем с этим файлом как с обычным XML:
ФайлХПС = Новый ЧтениеXML; ФайлХПС.ОткрытьФайл(Каталог + КодМарки + "\Documents\1\FixedDocument.fdoc"); ПутьКФайлу.Очистить(); Нормочасы.Очистить(); Пока ФайлХПС.Прочитать() Цикл ФайлХПС.ПрочитатьАтрибут(); Если ПроверитьЗначение(ФайлХПС.Значение) Тогда ЭлементыФормы.ПутьКФайлу.ДобавитьСтроку(); ЭлементыФормы.ПутьКФайлу.ТекущаяСтрока.Путь = ФайлХПС.Значение; КонецЕсли; КонецЦикла; ФайлХПС.Закрыть();
Все, имеем список файлов. Теперь приступаем к самим файлам. Файл страницы сам текстовый, но правила написания не XML. Структура блочная. Блоками отдельно пишется текстовая информация и графическая. Все блоки имеют координаты по оси Х и Y, для расположения на странице. Меня интересуют только текстовые блоки и их координаты, ну и их информация.
Блоки имеют начало и конец, понять где начало и конец просто: < />
В каждом блоке первое слово — его имя. Текстовые блоки имеют имя: Glyphs
Вот пример блока:
<Glyphs Fill="#ff000000" FontUri="/Documents/1/Resources/Fonts/DD1ED91D-300C-4E84-BACC-6412D0EB3F5F.odttf" FontRenderingEmSize="13.2795" StyleSimulations="None" OriginX="971.84" OriginY="59.68" Indices="19,55;26;17;19;21,55;17;21;19;20,55;24" UnicodeString="07.02.2015" />
Меня интересуют тут только параметры:
— OriginX, для определения колонок.
— UnicodeString как само значение того, что содержится в строке.
Читать придется как обычный текстовый файл. Текстовые блоки все пишутся одной строкой. В 1С можно прочитать строку до символа перевода коретки:
ФайлХПС = Новый ЧтениеТекста(Файл, КодировкаТекста.UTF8); Стр = ФайлХПС.ПрочитатьСтроку(); Пока Стр <> Неопределено Цикл СтруктураПараметров = ПроверитьИмяПараметра(Стр); ...
А полученную строку проверяем на параметр, если начинается на Glyphs, то берем на проверку и анализ, если нет — читаем следующий.
Придется строку анализировать побуквенно и переписывать в структуру.
Функция ВозвратитьРеквизитыПараметра(Строка) Перем ИмяПараметра, КоординатыПараметра; ИмяПараметра = ""; КоординатыПараметра = ""; Кавычка = """"; СтруктураПараметров = Новый Структура; Если Найти(Строка, "UnicodeString") > 0 Тогда Для Х = Найти(Строка, "UnicodeString") + 15 по СтрДлина(Строка) Цикл Буква = Сред(Строка, Х, 1); Если Буква <> """" Тогда ИмяПараметра = ИмяПараметра + Буква; Иначе СтруктураПараметров.Вставить("ИмяПараметра", ИмяПараметра); КонецЕсли; КонецЦикла; Для Х = Найти(Строка, "OriginX") + 9 по СтрДлина(Строка) Цикл Буква = Сред(Строка, Х, 1); Если Буква <> Кавычка Тогда КоординатыПараметра = КоординатыПараметра + Буква; Иначе СтруктураПараметров.Вставить("КоординатыПараметра", Число(КоординатыПараметра)); Возврат СтруктураПараметров; КонецЕсли; КонецЦикла; КонецЕсли; Возврат СтруктураПараметров; КонецФункции
Собственно, по выполнении функции, имеем все для анализа. Имя параметра, его координаты, значение параметра. Блоки выводят текст в XPS сверху вниз и слева направо. По координатам Х можно определить колонки, по названию параметра можем проанализировать какая информация нам нужна, а какая нет. Дальше расписывать как оно все уходило в справочник 1С не буду — там и так все понятно. Главное, я получил ответ как быстро извлечь нужную информацию из «графического» файла.
