[C++ Builder] Запись файла в формате Word

buka

Задача: засунуть текст, растр и табличку в Word Document, желательно вменяемым для Microsoft® Word® 97 образом.
Нужно один раз и не мне, поэтому желательно получить кусок работающего кода вместо ссылки в поиск. Ну или хотя бы статейку на эту тему.

Julie16

Может проще всего через rtf? Сохрани нужный тебе документ в ворде как rtf и открой файл ноутпадом. Я думаю все станет понятно.

buka

А может лучше в HTML?
Нет. Требования есть требования.

Julie16

rtf - нативный формат для ворда.

gopnik1994

Копай в сторону компонента TWordApplication на закладке Servers

buka

Полный застой.
Ни set_Text, ни InsertAfter не вставляют текст, а Word молчит как партизан.
В MSDN описывается Word 2003, а нужно делать для Word 97, и, видимо, есть значительная разница.
Как вариант можно создать временный гипертекст и открыть и сохранить через этот интерфейс, но как заставить впаять растр в документ?

buka

Может проще всего через rtf? Сохрани нужный тебе документ в ворде как rtf и открой файл ноутпадом. Я думаю все станет понятно.
Неправильно ты думаешь. Ворд записал туеву хучу какого-то хлама, в которой копаться себе дороже. Хотя это и нежелательное силовое решение... но есть простенькая по RTF?

Dasar

> Ворд записал туеву хучу какого-то хлама, в которой копаться себе дороже
Методом бинарного деления, находишь-то, что действительно там тебе необходимо.

Flack_bfsp

Ты знаешь хоть, что такое метод бинарного деления?

bastii

а через OLE Automation не катит?
только надо, чтобы word 97 был, т.к. в 2000ом изменилась объектная модель (не знаю как сильно)
потом заботай в VC++ директиву #import
дальше все просто
как делать в c++ Builder я не знаю
можно глянуть файл, который генерируется import, и передащить в Бильдер
или ручками запрогать через IDispatch (не уверен, что у ворда дуальные интерфейсы)
последнее проще делать в VBScript, VB, VBA, ... , но не в С++ (разве что ты в OLE хорошо рубишь и знаешь всякие helper-классы из MFC и ATL)
писать в doc файл самому - это гиблое дело
в любом случае понадобится заботать Structured Storages в OLE и поюзать DocView ютилитку из SDK, она позволяет просматривать SS

buka

а через OLE Automation не катит?
Оно-то и надобно
только надо, чтобы word 97 был, т.к. в 2000ом изменилась объектная модель (не знаю как сильно)
Вот-вот... К такому выводу я и пришел после часа мытарств.
потом заботай в VC++ директиву #import
дальше все просто
В Builder непременно.
можно глянуть файл, который генерируется import, и передащить в Бильдер
или ручками запрогать через IDispatch (не уверен, что у ворда дуальные интерфейсы)
Все уже есть
писать в doc файл самому - это гиблое дело
И мне так кажется.
разве что ты в OLE хорошо рубишь и знаешь всякие helper-классы из MFC и ATL
Не спец, да и с MFC и ATL Строитель не дружен
Cпасибо за поддержку!
Протрезвею малец и потычу через а Word_2k...

Dasar

да, согласен, метод бинарного удаления здесь лучше подходит.

bastii

в любом случае совет -- попрактиковаться на VBA в самом Word
можно включить запись макроса, поделать все ручками, а потом посмотреть что за код получился

yolki

Могу дать программу (правда на Delphi которая делает следующее:
Следит за буфером обмена и если он не пуст, то:
1) Вставляет в Word содержимое буфера обмена (с картинками, урлами и прочим)
2) Проигрывает звук
3) Очищает буфер обмена

yolki

Тут я подумал и решил код не распространять.
приведу основные идеи:

uses ... Word97..
type
I_WordApp = Word97.TWordApplication;
I_Document = Word97._Document;
файл Word97 есть в стандартной поставке Delphi 5, Delphi7 - наверняка для Билдера есть header, посмотри в папке PRogram Files\Borland\Builder\Ocx\Servers
С этим файлом (Word97) программа работает с любой версией офиса (>=97 проверялось на Office 97, Office XP, Office 2000, Office 2003

var
WordApp : I_WordApp;
Doc : I_Document;
Основные переменные для управления документом и вордом.
В секции Implementation потребовались ещё юниты. хедеры к ним думаю сам найдёшь.

uses
ComObj, // ну, это понятно
ActiveX, // это, думаю тоже
OleServer, // Это тоже из этой же серии
Clipbrd; // это чтобы с буфером обмена работать
Дальше так:

WordApp := I_WordApp.Create(nil);
WordApp.ConnectKind := ckRunningOrNew;
WordApp.Connect;
Doc:=WordApp.Documents.Add(EmptyParam,EmptyParam); // создаём новый пустой документ
После работы настоятельно рекомендую всё выключить и освободить - иначе процесс ворда останется висеть в памяти - у меня во время отладки один раз висело штук 15. глянул - ужаснулся.

Doc.Close(SaveChanges,EmptyParam,EmptyParam);
WordApp.Quit;
WordApp.Disconnect;
FreeAndNil(WordApp);
Сохранить документ:

Doc.SaveAs(FileName,EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam);
Поскольку я вставляю из буфера, то код для вставки текста и картинок на прямую тебе следует поискать самому.

var
P : Paragraph; // определён в Word97
begin
P:=Doc.Paragraps.Add(EmptyParam);
P.Range.Paste; // вставить в новый параграф содержимое буфера обмена
end;
собственно, всё.. Word не забудь отпустить! А то он у тебя будет файлы держать и не отпускать - ты их открыть не сможешь другим вордом (другим процессом). Когда сомневаешься - запусти taskmgr и прибей все процессы winword.exe

buka

Спасибо.
Хотя до всего этого я и сам дошел. Раскопал в Мусорке пару кусочков кода. Через OLE засунул картинку, таблицу тоже, вроде, смогу прибить
Оставить комментарий
Имя или ник:
Комментарий: