Использую uOpenOffice для формирования таблиц во Writer... пишу на Lazarus всё работает, сам дописывал функционал под свои нужды, кстати
как раз версия с добавленными мной процедурами и функциями, но в тексте примера куда-то пропали некоторые скобки... возможно что-то ещё...  
 
 Всё просто - файл ООо - это упакованная пачка хмл-документов... создаёте в редакторе то что хотели (Calc или Write), сохраняете в файл, распаковываете, и шаритесь по тексту в поисках нужной ноды, атрибута. После чего можете понять как к этому обратиться, а дальше дело техники - берёте DOM, XMLRead и XMLWrite и корректируете полученные файлы как надо, после чего запаковываете обратно, меняете расширение на .odt или какое там у эл.таблиц, открываете получившийся файл в редакторе и наслаждаетесь результатом. Никакого OLE никакого UNO всё просто до безобразия. 
 
 p.s.: естественно данный подход не даёт возможности работать в runtime, но зато гарантирует результат 

Собственно вот кусок "живого" кода, прямо из программы:
- Код: Выделить всё
- var f: TextFile;
 sh, wp, ep, c1, c2, s1l, s1r, s2, path: string;
 OoWriter: TOoWriter;
 Table: TTable;
 i: integer;
 
 function GetLinesCount: integer;
 begin
 ...
 end;
 
 function GetCaption: string;
 begin
 ...
 end;
 
 function GetMOL: string;
 begin
 ...
 end;
 
 function GetAuthorAndTime: string;
 begin
 ...
 end;
 
 procedure GetSourceAndComment;
 begin
 ...
 end;
 
 procedure GetSt;
 begin
 ...
 end;
 begin
 // Если ничего не выделено - выйдем
 if DocsG.Row=0 then exit;
 // Синхронизируем БД и таблицу
 DocsGSelection(nil,1,1);
 // Загрузим строки документа в IQ
 LoadDocStringsInIQ(DQ.FieldByName('docs_id').AsString);
 // Создадим файл
 OoWriter:=TOoWriter.Create;
 // Подгрузим шаблон
 if not OoWriter.LoadTemplate('blank.odt') then exit;
 // Подпишемся
 OoWriter.Generator:='LeoSKL';
 OoWriter.Author:='Leo';
 // Вставим данные
 OoWriter.FindAndReplace('_Контакты',GetContacts);
 OoWriter.FindAndReplace('_Заголовок',GetCaption);
 OoWriter.FindAndReplace('_МОЛ',GetMOL);
 OoWriter.FindAndReplace('_АвторВремя',GetAuthorAndTime);
 GetSourceAndComment;
 OoWriter.FindAndReplace('_Основание',c1);
 OoWriter.FindAndReplace('_Комментарий',c2);
 // Заполним таблицу
 Table:=OoWriter.GetTable('Таблица1');
 Table.MultiplyRow(1,GetLinesCount-1);
 i:=1;
 while not IQ.EOF do begin
 with Table do begin
 FindAndReplace(i,'_№',IntToStr(i));
 FindAndReplace(i,'_Наим',IQ.FieldByName('name').AsString);
 FindAndReplace(i,'_Колич',IQ.FieldByName('count').AsString);
 FindAndReplace(i,'_ЕдИзм',IQ.FieldByName('meas').AsString);
 FindAndReplace(i,'_Цена',IQ.FieldByName('price').AsString);
 FindAndReplace(i,'_Сумма',IQ.FieldByName('sum').AsString);
 end;
 inc(i);
 IQ.Next;
 end;
 Table.FindAndReplace(i,'_Итого',GetFromBase('select sum(sum) '+
 'from doc_strings where docs_id='+DQ.FieldByName('docs_id').AsString));
 // Вставим остальные данные
 GetSt;
 OoWriter.FindAndReplace('_Строка1Слева',s1l);
 OoWriter.FindAndReplace('_Строка1Справа',s1r);
 OoWriter.FindAndReplace('_Строка2',s2);
 OoWriter.ShowDocument;
 end;