Есть ситуации, когда нет возможности установить Excel на стороне клиента, а нужно загружать в базу данные *.xls файлов. Спасением является бесплатный 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.
Вот и все. Как вы смогли убедиться - работа с Calc`ом не сложнее таковой с Microsoft Excel.