Контекст
Из отчета по чекам ofd.ru нужно получать ссылки на сформированные чеки, но ссылки реализованы не в виде обычной строки, а в виде гиперссылки. Типовой механизм загрузки Excel файла через ТабличныйДокумент.Прочитать() такие ссылки не видит.
Было опробовано 2 варианта (оба рабочих):
1. Использование COM объекта. Метод в принципе рабочий, но очень низкая производительность.
2. Использование того факта, что xlsx по сути архив с xml документами.
Ограничения
Здесь не приводится законченное решение, только подход. У меня формат файла жёстко зафиксирован, поэтому универсальные решения не рассматривались.
Получение ссылок через распаковку архива
Общий принцип следующий - получаем файл ссылок "sheet1.xml.rels" - сохраняем из него соответствие идентификаторов ссылкам, а затем обрабатываем файл листа "sheet1.xml".
&НаСервере
Процедура ЗагрузитьДанныеЧековОФД(Адрес)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
ИмяВременногоКаталога = ПолучитьИмяВременногоФайла();
Ссылки = Новый Соответствие;
Попытка
ДвоичныеДанные.Записать(ИмяВременногоФайла);
ЧтениеАрхива = Новый ЧтениеZipФайла(ИмяВременногоФайла);
ЭлементАрхиваДанные = ЧтениеАрхива.Элементы.Найти("sheet1.xml");
ЭлементАрхиваСсылки = ЧтениеАрхива.Элементы.Найти("sheet1.xml.rels");
ЧтениеАрхива.Извлечь(ЭлементАрхиваДанные, ИмяВременногоКаталога, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
ЧтениеАрхива.Извлечь(ЭлементАрхиваСсылки, ИмяВременногоКаталога, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
ЧтениеАрхива.Закрыть();
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяВременногоКаталога + "/sheet1.xml.rels");
ПостроительDOM = Новый ПостроительDOM;
Документ = ПостроительDOM.Прочитать(ЧтениеXML);
ЧтениеXML.Закрыть();
Если Документ.ДочерниеУзлы.Количество() = 1 Тогда
Для каждого ЭлементСсылки Из Документ.ДочерниеУзлы[0].ДочерниеУзлы Цикл
Тип = ЭлементСсылки.ПолучитьАтрибут("Type");
ИД = ЭлементСсылки.ПолучитьАтрибут("Id");
ЗначениеСсылки = ЭлементСсылки.ПолучитьАтрибут("Target");
Если Тип <> "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Тогда
Продолжить;
КонецЕсли;
Ссылки.Вставить(ИД, ЗначениеСсылки);
КонецЦикла;
КонецЕсли;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяВременногоКаталога + "/sheet1.xml");
ПостроительDOM = Новый ПостроительDOM;
Документ = ПостроительDOM.Прочитать(ЧтениеXML);
ЧтениеXML.Закрыть();
Если Документ.ДочерниеУзлы.Количество() = 1 Тогда
УзелКниги =Документ.ДочерниеУзлы[0];
Для каждого ЭлементЛиста Из УзелКниги.ДочерниеУзлы Цикл
Если Тип(ЭлементЛиста) <> Тип("ЭлементDOM")
Или ЭлементЛиста.ИмяУзла <> "hyperlinks" Тогда
Продолжить;
КонецЕсли;
Для каждого ЭлементСсылки Из ЭлементЛиста.ДочерниеУзлы Цикл
АдресЯчейки = ЭлементСсылки.ПолучитьАтрибут("ref");
ИД = ЭлементСсылки.ПолучитьАтрибут("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id");
Ссылка = Ссылки[ИД];
Если Ссылка <> Неопределено Тогда
НоваяСтрокаСсылки = ТаблицаСсылок.Добавить();
НоваяСтрокаСсылки.АдресЯчейки = АдресЯчейки;
НоваяСтрокаСсылки.Ссылка = Ссылка;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
Исключение
КонецПопытки;
УдалитьФайлы(ИмяВременногоФайла);
УдалитьФайлы(ИмяВременногоКаталога);
КонецПроцедуры
Платформа 8.3.14.