| View previous topic :: View next topic |
| Author |
Message |
sebarnolds General User

Joined: 19 Oct 2009 Posts: 6
|
Posted: Tue Oct 20, 2009 2:53 am Post subject: Export to PDF [Delphi] |
|
|
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 |
|
 |
B Marcelly Super User

Joined: 12 May 2004 Posts: 1414 Location: France
|
Posted: Tue Oct 20, 2009 10:38 pm Post subject: |
|
|
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 |
|
 |
sebarnolds General User

Joined: 19 Oct 2009 Posts: 6
|
Posted: Tue Oct 20, 2009 11:06 pm Post subject: |
|
|
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 |
|
 |
bitfarmer General User

Joined: 06 May 2004 Posts: 39 Location: Murcia, Spain
|
Posted: Thu Oct 22, 2009 1:04 am Post subject: |
|
|
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 |
|
 |
sebarnolds General User

Joined: 19 Oct 2009 Posts: 6
|
Posted: Thu Oct 22, 2009 4:05 am Post subject: |
|
|
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 |
|
 |
bitfarmer General User

Joined: 06 May 2004 Posts: 39 Location: Murcia, Spain
|
Posted: Thu Oct 22, 2009 4:41 am Post subject: |
|
|
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 |
|
 |
sebarnolds General User

Joined: 19 Oct 2009 Posts: 6
|
Posted: Thu Oct 22, 2009 6:24 am Post subject: |
|
|
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 |
|
 |
bitfarmer General User

Joined: 06 May 2004 Posts: 39 Location: Murcia, Spain
|
Posted: Fri Oct 23, 2009 12:37 am Post subject: |
|
|
| I use Delphi 7 |
|
| Back to top |
|
 |
|
|
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
|