Загрузка файла MS Excel в 1С через OpenOffice/LibreOffice

Пример загрузки файла Excel с помощью бесплатного пакета OpenOffice (либо LibreOffice, т.к. работа через COM с ними абсолютно одинакова).

Процедура загрузки из файла

Функция ЗагрузитьТЗизФайла(ПутьКФайлу)

//OpenOffice Calc//////////////////////////////////////////////////////////////////////////////////////////////
Попытка
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
Исключение
Предупреждение(ОписаниеОшибки() + Символы.ПС + "программа OpenOffice\LibreOffice не установлена на данном компьютере!");
Возврат Неопределено;
КонецПопытки;
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");
Свойства = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
Свойства.Name = "AsTemplate";
Свойства.Value = Истина;
Args = Новый COMSafeArray("VT_VARIANT", 2);
Args.SetValue(0, Свойства);
Свойства1 = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
Свойства1.Name = "Hidden";
Свойства1.Value = Истина;
Args.SetValue(1,Свойства1);
Document = Desktop.LoadComponentFromURL(ПривестиФайлКУРЛ(ПутьКФайлу), "_blank", 0, Args);
Sheets = Document.getSheets();
Sheet = Sheets.getByIndex(текЛист-1);
локТабЗнач = Новый ТаблицаЗначений;
begCol = 0;
begRow = 0;
endCol = Sheet.Data.GetLength(6) - 1;
endRow = Sheet.Data.GetLength() - 1;
нКол = 0;
локТабЗнач.Колонки.Очистить();

КС = Новый КвалификаторыСтроки(50);
Массив = Новый Массив;
Массив.Добавить(Тип("Строка"));

ОписаниеТиповСтрока = Новый ОписаниеТипов(Массив, , КС);

Пока нКол <= endCol Цикл
ИмяКол = "К"+Строка(нкол+1);
локТабЗнач.Колонки.Добавить(ИмяКол,ОписаниеТиповСтрока);
нКол = нКол + 1;
КонецЦикла;
Range = Sheet.getCellRangeByPosition(begCol, begRow, endCol, endRow);
МассивКом = Новый COMSafeArray("VT_VARIANT", Range.Columns.Count, Range.Rows.Count);
МассивКом = Range.getDataArray();
тмпПростойМассив = МассивКом.Выгрузить();
Для каждого массив из тмпПростойМассив Цикл
ит = 0;
НовСтрока = локТабЗНач.Добавить();
Для каждого ЭлементМассива из массив цикл
НовСтрока[ит] = ЭлементМассива;
ит = ит + 1;
КонецЦикла;
КонецЦикла;
Возврат локТабЗнач;

КонецФункции

Как  видно из функции  ЗагрузитьТЗизФайла - читается сразу вся область данных файла, поэтому с быстродействием все отлично. На выходе имеем готовую таблицу значений. В данном случае каждой колонке определен тип Строка(50), но можно этого и не делать, просто это нужно, если собираетесь, например, помещать ее во временную таблицу. 

Процедура ВыгрузитьТЗвФайл(ТаблицаРезультата)

//OpenOffice Calc///////////////////////////////////////////////////////////////////////////
Попытка
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
Исключение
Предупреждение(ОписаниеОшибки() + Символы.ПС + "программа OpenOffice не установлена на данном компьютере!");
Возврат;
КонецПопытки;
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");
Свойства = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
Свойства.Name = "AsTemplate";
Свойства.Value = Истина;
Args = Новый COMSafeArray("VT_VARIANT", 3);
Args.SetValue(0, Свойства);
Свойства1 = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
Свойства1.Name = "Hidden";
Свойства1.Value = Истина;
Args.SetValue(1, Свойства1);
Document = Desktop.LoadComponentFromURL("private:factory/scalc", "_blank", 0, Args);
Sheets = Document.getSheets();
Sheet = Sheets.getByIndex(0);
мИтКол = 0;
Для каждого кол из ТаблицаРезультата.Колонки Цикл
Sheet.getCellByPosition(мИтКол,0).setString(кол.Имя);
мИтКол = мИтКол + 1;
КонецЦикла

ВсегоСтрок = ТаблицаРезультата.Количество();
ВсегоКолонок = ТаблицаРезультата.Колонки.Количество();
МассивКОМ = Новый COMSafeArray("VT_VARIANT", ВсегоСтрок,ВсегоКолонок);
иткол = 0;
итстр = 0;

Для каждого стр из ТаблицаРезультата Цикл
Для каждого кол из ТаблицаРезультата.Колонки Цикл
стрРез = СокрЛП(стр[кол.Имя]);
МассивКОМ.SetValue(итстр,иткол,стрРез);
иткол = иткол+1;
КонецЦикла;
иткол = 0;
итстр = ?(итстр=ВсегоСтрок,0,итстр+1);
КонецЦикла;
begCol = 0;
begRow = 1;
endCol = ВсегоКолонок-1;
endRow = ВсегоСтрок;
Range = Sheet.getCellRangeByPosition(begCol, begRow, endCol, endRow);
Range.setDataArray(МассивКОМ);
//Document.storeToURL(ПривестиФайлКУРЛ(ПутьКФайлу),Args);
Свойства2 = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
Свойства2.Name = "FilterName";
Свойства2.Value = "MS Excel 97";
Args.SetValue(2,Свойства2);
Document.GetCurrentController().GetFrame().GetContainerWindow().SetVisible(Истина);
//Document.storeToURL(ПривестиФайлКУРЛ(ФайлКартотеки),Args);

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

Процедура  ВыгрузитьТЗвФайл сохраняет любую таблицу значений в файл MS Excel. В текущем примере откроется OpenOffice/LibreOffice Calc  c данными переданной таблицы значений. Если раскомментировать строки:

//Document.storeToURL(ПривестиФайлКУРЛ(ПутьКФайлу),Args);

...................................................

//Document.storeToURL(ПривестиФайлКУРЛ(ФайлКартотеки),Args);

и закомментировать

Document.GetCurrentController().GetFrame().GetContainerWindow().SetVisible(Истина);

при этом добавив Параметр ПутьКФайлу, то данные запишутся в файл без открытия Calc`a. Если обратить внимание на сохранение, то сразу бросается двойной вызов  Document.storeToURL - это необходимо для корректного сохранения в формате MS Excel.

Функция ПривестиФайлКУРЛ(ПутьКФайлу)

ПутьКФайлу = СтрЗаменить(ПутьКФайлу," ","%20");
ПутьКФайлу = СтрЗаменить(ПутьКФайлу,"\","/");
Возврат "file:/" + "/localhost/" + ПутьКФайлу;

Конецфункции

Функция  ПривестиФайлКУРЛ просто приводит путь к виду, необходимому OpenOffice/LibreOffice.

Добавить комментарий