?
Solved

Converting OLEContainer MS Office files back to native files which can be opened by Office Apps.

Posted on 2006-06-08
9
Medium Priority
?
1,611 Views
Last Modified: 2010-04-05
Hi,

I have MS Office documents (DOC, XLS, MSG) which have been wrapped in an OLE Container and strored in a database blobfield.

I need to automatically read these documents onto hard disk folders - in their original native format, so that users can use the Office Apps to open them as native documents.

This is not a problem for Word Docs because I can read the blob into an OLE COntainer and use OleContainer1.SaveAsDocument() but this does not work for XLS and MSG files.

For XLS and MSG, I can open/edit the OLE COntainer and use the File-SaveCopyAs menu command - and this works - but it is manual and I need to automate the process as there are 000's of documents.

Any pointers would be gratefully received!

William.
0
Comment
Question by:Crannburn
  • 5
  • 4
9 Comments
 
LVL 10

Expert Comment

by:atul_parmar
ID: 16862630
OleContainer1.OleObject.SaveAs(FileName);
0
 

Author Comment

by:Crannburn
ID: 16863790
I love it! So Simple - thank you.

That's my question answered, but if you knew how I could save to a Stream instead of disk, I would be doubly grateful! (It would make the conversion so much faster I think).

Thanks,
Wm.
0
 
LVL 10

Accepted Solution

by:
atul_parmar earned 2000 total points
ID: 16868239
Hi William,

You said that
"I need to automatically read these documents onto hard disk folders - in their original native format, so that users can use the Office Apps to open them as native documents." So I guess, first you will save it to stream and then to disk. I don't think this will fasten the process (I've not tested but just guessing).

You can save it stream by OleContainer1.SaveToStream method but this way the file will not be saved in its native format and to save it in its native format you will have to go use the oleobject's save method.

Another way is to use native VCL (I couldn't recall but sure there are some third party VCL components available) what allows you to save the content to native office format. That will really fasten the process and the good thing is that it doesn't require ms-office to be installed.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:Crannburn
ID: 16868278
ok - thats good to know. I will use the OleObject.SaveAs to begin with and if the whole process is too slow then I will hunt down some components.

Thanks again for the help!

Wm.
0
 
LVL 10

Expert Comment

by:atul_parmar
ID: 16868282
You can also use
OleContainer1.OleObject.SaveCopyAs(FileName);
0
 

Author Comment

by:Crannburn
ID: 16887369
Atul,

I have the above working for DOC and XLS but not for MSG and HTM files. THe OleContainer.OleObject.SaveAs() gives an error 'Interface Not Supported'.

I can use OleContainer.DoVerb(0) to display the file and Save As manually for .msg and .htm.

Can you still help?

Thanks,
Wm.
0
 
LVL 10

Expert Comment

by:atul_parmar
ID: 16892125
Hi william,

Can you tell me how you are loading the .msg and .htm files to tolecontainer?
e.g. for .msg

  OleContainer1.CreateObject('outlook.application', false);
  OleContainer1.OleObject.CreateItemFromTemplate('c:\myitem.msg');

or something else?
0
 

Author Comment

by:Crannburn
ID: 16892309
The original code was not mine, and is complicated by the use of ASTA. The Binary['DATA'] is reference to the binary field in the business object, which is subsequently sent via sockets to the application server and stored. The code below is used for all file types (doc, xls, msg, htm) except pdf which is stored in native format.

Wm.

   If SameText(ExtractFileExt(FileName),'.PDF') then begin
      FStream := TFileStream.Create(FileName,fmOpenRead);
      Try
       Binary['DATA'] := FStream;
      Finally
       FStream.Free;
      end;
   end else begin
     OleContainer := TOleContainer.Create(nil);
     Try
      OleContainer.Parent  := Form;// Assuming there is a form
      OleContainer.visible := False;
      OleContainer.CreateObjectFromFile(FileName,True);
      MStream := TMemoryStream.Create;
      Try
       OleContainer.SaveToStream(MStream);
       Binary['DATA'] := MStream;
      Finally
       MStream.Free;
      end;
     Finally
      OleContainer.Free;
     end;
   end;
0
 
LVL 10

Expert Comment

by:atul_parmar
ID: 16893363
William,

when we create an ole object with
OleContainer.CreateObjectFromFile(FileName,True);
it creates appropriate ole object for e.g. word, excel for .doc and .xls files respectively. But with .msg and .htm files it does not creates the outlook and browser object. so we can not save it directly to its native format.

one way to do this is to explicitly create outlook and browser object for .msg and .htm files and then call its save method. The code may require to branch based upon file type. as OUTLOOK and BROWSER requires different implementation.

OUTLOOK
var
  mailitem : olevariant;
begin  
  OleContainer1.CreateObject('Outlook.Application', True); // create outlook object
  mailitem := OleContainer1.OleObject.CreateItemFromTemplate(FileName); // open file
  mailitem.SaveAs('c:\newitem.msg', olMSG);
end
Note: When you call SaveAs the outlook displays a security alert. you can supress this by registering your application as trusted application for outlook.

HTML
var
  PersistStream: IPersistStreamInit;
  FileStream: TFileStream;
  Stream: IStream;
begin
  OleContainer1.CreateObject('Shell.Explorer', True);
  OleContainer1.OleObject.Navigate(FileName);
  while OleContainer1.OleObject.ReadyState <= READYSTATE_LOADED      do
    Application.ProcessMessages;
  PersistStream := IDispatch(OleContainer1.OleObject.Document) as IPersistStreamInit;
  FileStream := TFileStream.Create('c:\new.htm', fmCreate);
  try
    Stream := TStreamAdapter.Create(FileStream, soReference)
              as IStream;
    if Failed(PersistStream.Save(Stream, True)) then
      ShowMessage('SaveAs HTML fail!');
  finally
    FileStream.Free;
  end;
end

As you can see the HTML version is slight complex as it does not have SaveAs method.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question