OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

Export to PDF [Delphi]

 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API
View previous topic :: View next topic  
Author Message
sebarnolds
General User
General User


Joined: 19 Oct 2009
Posts: 6

PostPosted: Tue Oct 20, 2009 2:53 am    Post subject: Export to PDF [Delphi] Reply with quote

Hello.

I am trying to use OpenOffice to export ODT files to PDF. I am using Delphi 6 with OpenOffice 3 and OLE. I used to code from another post: http://www.oooforum.org/forum/viewtopic.phtml?p=344977. However it seems it always produces a modified ODT file (the saved file has a size near the size of the original file and the header seems to be the same) instead of a PDF.

Here is the code:
Code:

unit unOpenOfficePDF;

interface

uses ComObj, Variants, sysutils;

function ExportToPDF(InFileName, OutFileName:string) : Boolean;

type
  TOOoWriter = class(TObject)
  private
    fOpenOffice : Variant;
    fDocument : Variant;
    fConnected : boolean;
    fDocumentOpened : boolean;
    fDesktop : Variant;
    {fHTMLSrc : boolean;}

    function MakePropertyValue(PropName:string; PropValue:variant):variant;
  public
     Constructor Create;
     destructor Destroy; override;

     function Connect : boolean;
     procedure Disconnect;

     function OpenDocument(Filename:string):boolean;
     procedure SaveToPDF(FileName:string);
     procedure CloseDocument;
  end;

implementation

uses
   ActiveX;

{ TOOoWriter }

procedure TOOoWriter.CloseDocument;
begin
    if fDocumentOpened then
    begin
       fDocument.Close(false);

       fDocumentOpened := false;
       fDocument := Unassigned;

       fDesktop.Terminate;
       fDesktop := UnAssigned;
    end;
end;

function TOOoWriter.Connect: boolean;
begin
    if  VarIsEmpty(fOpenOffice) then
        fOpenOffice := CreateOleObject('com.sun.star.ServiceManager');

    fConnected := not (VarIsEmpty(fOpenOffice) or VarIsNull(fOpenOffice));
    Result := fConnected;
end;

constructor TOOoWriter.Create;
begin
  inherited;
  CoInitialize(nil);
end;

destructor TOOoWriter.Destroy;
begin
  CoUninitialize;
  inherited;
end;

procedure TOOoWriter.Disconnect;
begin
    if fDocumentOpened then
       CloseDocument;

    fConnected := false;
    fOpenOffice := Unassigned;
end;

function TOOoWriter.MakePropertyValue(PropName: string;
  PropValue: variant): variant;
var
   Struct: variant;
begin
    Struct := fOpenOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
    Struct.Name := PropName;
    Struct.Value := PropValue;
    Result := Struct;
end;

function TOOoWriter.OpenDocument(Filename: string): boolean;
var
   wProperties : Variant;
   wViewSettings : Variant;
   wController : Variant;
begin
   if not fConnected then
      abort;

   fDesktop := fOpenOffice.createInstance('com.sun.star.frame.Desktop');

   wProperties := VarArrayCreate([0, 0], varVariant);
   wProperties[0] := MakePropertyValue('Hidden', True);

   fDocument := fDesktop.loadComponentFromURL('file:///'+ StringReplace(FileName, '\', '/', [rfIgnoreCase, rfReplaceAll]) , '_blank', 0, wProperties);

   fDocumentOpened := not (VarIsEmpty(fDocument) or VarIsNull(fDocument));

   {
   fHTMLSrc := pos('.htm', lowercase(extractfileext(Filename))) > 0;

   if fDocumentOpened and fHTMLSrc then
   begin
     wController := fDocument.Getcurrentcontroller;
     if not (VarIsEmpty(wController) or VarIsNull(wController)) then
     begin
        wViewSettings := wController.getviewsettings;
        if not (VarIsEmpty(wViewSettings) or VarIsNull(wViewSettings)) then
           wViewSettings.ShowOnlineLayout := false;
     end;
     wViewSettings := Unassigned;
     wController := Unassigned;
   end;
   }

   result := fDocumentOpened;
end;

procedure TOOoWriter.SaveToPDF(FileName: string);
var
   wProperties: variant;

begin
   if not (fConnected and fDocumentOpened) then
      abort;

   wProperties := VarArrayCreate([0, 3], varVariant);
   {
   if fHTMLSrc then
      wProperties[0] := MakePropertyValue('FilterName', 'writer_web_pdf_Export')
   else
   }
   wProperties[0] := MakePropertyValue('FilterName', 'HTML (StarWriter)' {'writer_pdf_Export'});

   wProperties[1] := MakePropertyValue('CompressionMode', '1');
   wProperties[2] := MakePropertyValue('Pages', 'All');
   wProperties[3] := MakePropertyValue('Overwrite', TRUE);

   fDocument.StoreToURL('file:///'+ StringReplace(FileName, '\', '/', [rfIgnoreCase, rfReplaceAll]), wProperties);
end;


And I call the conversion with the following procedure:
Code:

function ExportToPDF(InFileName, OutFileName:string) : Boolean;
var
   wWriter : TOOoWriter;
begin
   try
      wWriter := TOOoWriter.Create;
      try
        if wWriter.Connect then
        try
           if wWriter.OpenDocument(InFileName) then
           try
              wWriter.SaveToPDF(OutFileName);
           finally
              wWriter.CloseDocument;
           end;
        finally
           wWriter.Disconnect;
        end;
      finally
         wWriter.free;
      end;
      Result := True;
   except
      on e:exception do
      begin
        Result := False;
         //response.content := 'PDF Document Error: '+e.message;
      end;
   end;
end;


I looked on the documentation / sdk / forums and it seems the filtername and the api should be the same but something doesn't work. Anybody here can help me ?

Thanks,
Sebastien
Back to top
View user's profile Send private message
B Marcelly
Super User
Super User


Joined: 12 May 2004
Posts: 1453
Location: France

PostPosted: Tue Oct 20, 2009 10:38 pm    Post subject: Reply with quote

Hi,
Some remarks on your code
Code:
   wProperties[0] := MakePropertyValue('FilterName', 'HTML (StarWriter)' {'writer_pdf_Export'});
// incorrect FilterName value.   Use :  writer_web_pdf_Export


   wProperties[1] := MakePropertyValue('CompressionMode', '1');
// Obsolete option. Since OOo 2 you must set options in parameter FilterOptions
// see http://wiki.services.openoffice.org/wiki/API/Tutorials/PDF_export

   wProperties[2] := MakePropertyValue('Pages', 'All');
// Incorrect parameter value in the original thread (so the API ignored it). This parameter is now obsolete.
// see http://wiki.services.openoffice.org/wiki/API/Tutorials/PDF_export
// anyway, by default all pages are output.

   wProperties[3] := MakePropertyValue('Overwrite', TRUE);
// useless - this is the default value

   fDocument.StoreToURL('file:///'+ StringReplace(FileName, '\', '/', [rfIgnoreCase, rfReplaceAll]), wProperties);
// this conversion to URL by StringReplace does not work for national characters

  fDocument.Close(false);
// common usage is :  fDocument.close(true);



______
Bernard
Back to top
View user's profile Send private message Visit poster's website
sebarnolds
General User
General User


Joined: 19 Oct 2009
Posts: 6

PostPosted: Tue Oct 20, 2009 11:06 pm    Post subject: Reply with quote

Hello and thank you for your quick answer.

The filtername was something I set when trying something else, I obviously tried before with the right name.

Anyway, here is my corrected code:
Code:

   wProperties := VarArrayCreate([0, 0], varVariant);
   wProperties[0] := MakePropertyValue('FilterName', 'writer_pdf_Export');

   fDocument.StoreToURL('file:///C:/test.pdf', wProperties);


Also, I replaced the fDocument.Close(false) line by fDocument.Close(true).

As I expected I get the same result : an ODT file. I opened the source and "pdf" files with 7zip and both mimetype files contains "application/vnd.oasis.opendocument.text".

Thanks.
Back to top
View user's profile Send private message
bitfarmer
General User
General User


Joined: 06 May 2004
Posts: 39
Location: Murcia, Spain

PostPosted: Thu Oct 22, 2009 1:04 am    Post subject: Reply with quote

I would try without all those "TRY"s, may be they are marsking some ugly errors from you... in test mode, I always switch off the trys, I WANT to see the errors produced.

For instance, if something goes wrong here (wProperties[0] := MakePropertyValue('FilterName', 'HTML (StarWriter)' {'writer_pdf_Export'}); ) you end up with a ODT file reanmed to PDF, just as you are getting!

Good hunting, anyway!
Back to top
View user's profile Send private message Visit poster's website
sebarnolds
General User
General User


Joined: 19 Oct 2009
Posts: 6

PostPosted: Thu Oct 22, 2009 4:05 am    Post subject: Reply with quote

All right.... WTF !

Removing the "try" didn't help at all.

However, I just tried something else which worked... only I don't know why.

I replaced:
Code:

wProperties[0] := MakePropertyValue('FilterName', 'writer_pdf_Export');

by
Code:

wProperties[0] := fOpenOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
wProperties[0].Name := 'FilterName';
wProperties[0].Value := 'writer_pdf_Export';

(i.e. the exact same content as the function).

What could be happening in that function that screw the result ?

If anybody has an idea, I would gladly hear it. Otherwise, I'll just try to work around the issue. Note that I am using Delphi 6 (don't know if it matters).

Anyway thank you for your help.
Back to top
View user's profile Send private message
bitfarmer
General User
General User


Joined: 06 May 2004
Posts: 39
Location: Murcia, Spain

PostPosted: Thu Oct 22, 2009 4:41 am    Post subject: Reply with quote

Then try again with the function but instead of...

Code:

function TOOoWriter.MakePropertyValue(PropName: string;
  PropValue: variant): variant;
var
   Struct: variant;
begin
    Struct := fOpenOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
    Struct.Name := PropName;
    Struct.Value := PropValue;
    Result := Struct;
end;


..try better this...

Code:

function TOOoWriter.MakePropertyValue(PropName: string;
  PropValue: variant): variant;
begin
    Result := fOpenOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
    Result .Name := PropName;
    Result .Value := PropValue;
end;


Copying one variant into other can be not very stable, and may be this was the only reason... anyway, my similar function is not the same as your and does the job right, if you wanna try:

Code:

function TDocumentoTexto.ooCreateValue(ooName: string; ooData: variant): variant;
var
  ooReflection: variant;
begin
  if IsOpenOffice then begin
    ooReflection:= Programa.createInstance('com.sun.star.reflection.CoreReflection');
    ooReflection.forName('com.sun.star.beans.PropertyValue').createObject(result);
    result.Name := ooName;
    result.Value:= ooData;
  end else begin
    raise Exception.Create('ooValue imposible to create, load OpenOffice first!');
  end;
end;
Back to top
View user's profile Send private message Visit poster's website
sebarnolds
General User
General User


Joined: 19 Oct 2009
Posts: 6

PostPosted: Thu Oct 22, 2009 6:24 am    Post subject: Reply with quote

I tried both methods but none seems to work on my computer.

BTW, can you tell me which version of Delphi you use ?

Sebastien
Back to top
View user's profile Send private message
bitfarmer
General User
General User


Joined: 06 May 2004
Posts: 39
Location: Murcia, Spain

PostPosted: Fri Oct 23, 2009 12:37 am    Post subject: Reply with quote

I use Delphi 7
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group