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

Joined: 28 Jul 2005 Posts: 10
|
Posted: Thu Jul 28, 2005 8:10 am Post subject: Delphi and OOWriter ExportToPDF |
|
|
Hi everyone,
I have this Delphi object that I use to successfully convert files (like .DOC and .SWX) to PDF files using OOo.
Unfortunatly I've recently found that HTML (.HTM) files throw an exception and I'm hoping that someone else here has seen this behavior before and can tell me what I'm doing wrong or if it's a known issue with OOWriter.
Here is the code:
| Code: |
*** Interface ***
type
TOOoWriter = class(TObject)
private
fOpenOffice : Variant;
fDocument : Variant;
fConnected : boolean;
fDocumentOpened : boolean;
fDesktop : Variant;
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 ***
{ 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;
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:///'+ StripString(FileName, ['\'], '/') , '_blank', 0, wProperties);
fDocumentOpened := not (VarIsEmpty(fDocument) or VarIsNull(fDocument));
result := fDocumentOpened;
end;
procedure TOOoWriter.SaveToPDF(FileName: string);
var
wProperties: variant;
begin
if not (fConnected and fDocumentOpened) then
abort;
wProperties := VarArrayCreate([0, 0], varVariant);
wProperties[0] := MakePropertyValue('FilterName', 'writer_pdf_Export');
fDocument.StoreToURL('file:///'+ StripString(FileName, ['\'], '/'), wProperties);
end;
|
The code fails on the final line of the SaveToPDF routine, but only if I try to export a loaded .HTM file. So far any other filetype causes me no problem. Is this a known issue or am I doing something wrong.
This StripString function just does a replacement of '\' to '/'.
Any help with this would be great.
Ryan. |
|
| Back to top |
|
 |
sllimr7139 General User

Joined: 28 Jul 2005 Posts: 10
|
Posted: Thu Jul 28, 2005 8:45 am Post subject: Solved: At least partially.... |
|
|
Ok so after I posted this question I decided to look at my filter string a little more and this is what I've found out.
There is a secondary filter string that is used, and it appears to be specifically, for Web documents. The filter string is "writer_web_pdf_Export". So I modified the SaveToPDF procedure on my OOWriter object to the following:
| Code: |
...
procedure TOOoWriter.SaveToPDF(FileName: string; HTMLSrc:boolean = false);
var
wProperties: variant;
begin
if not (fConnected and fDocumentOpened) then
abort;
wProperties := VarArrayCreate([0, 0], varVariant);
if HTMLSrc then
wProperties[0] := MakePropertyValue('FilterName', 'writer_web_pdf_Export')
else
wProperties[0] := MakePropertyValue('FilterName', 'writer_pdf_Export');
fDocument.StoreToURL('file:///'+ StripString(FileName, ['\'], '/'), wProperties);
end;
...
|
This change has allowed me to export my HTML documents to PDF properly. Now the only problems I'm having is that the exported PDF is not retaining the formatting of the orignal .HTM document and that the resulting PDF document insists on printing Landscape only inside of Acrobat. I can't seem to force it to print Portrait which is very annoying.
Oh well, at least I've figured out the HTML -> PDF thing. <grin>
Ryan. |
|
| Back to top |
|
 |
sllimr7139 General User

Joined: 28 Jul 2005 Posts: 10
|
Posted: Thu Jul 28, 2005 12:08 pm Post subject: By jove I think I've got it! |
|
|
It appears that the landscape vs. portrait printing problems when I export an HTML document to PDF from OOWriter is due to the Online Layout property.
So to correct this problem I've added the following code to my previously listed component.
| Code: |
...
function TOOoWriter.OpenDocument(Filename: string; HTMLSrc:boolean = false): boolean;
var
wProperties : Variant;
wLayout : 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:///'+ StripString(FileName, ['\'], '/') , '_blank', 0, wProperties);
fDocumentOpened := not (VarIsEmpty(fDocument) or VarIsNull(fDocument));
if fDocumentOpened then
begin
wLayout := fDocument.Getcurrentcontroller.getviewsettings;
if not (VarIsEmpty(wLayout) or VarIsNull(wLayout)) then
begin
wLayout.ShowOnlineLayout := false;
end;
wLayout := Unassigned;
end;
result := fDocumentOpened;
end;
...
|
The code should probably have more checks in it to confirm that the fDocument object actually returned a proper GetCurrentController reference but at this time I'm not too concerned about it. I'll probably go back and clean up the code when I put it into production.
Ryan. |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
sllimr7139 General User

Joined: 28 Jul 2005 Posts: 10
|
Posted: Fri Jul 29, 2005 9:49 am Post subject: |
|
|
| Quote: |
sllimr7139,
Thank you for this code.
|
No problem. I've actually been thinking about making a set of components for each of the different OOo sections but at this time they're just going to have to be a set of classes.
If anyone's interested in the final code for that class just leave me a message and I'll post my final class code in full.
Ryan. |
|
| Back to top |
|
 |
Opp Newbie

Joined: 13 Aug 2005 Posts: 4
|
Posted: Sat Aug 13, 2005 3:35 pm Post subject: |
|
|
Hi sllimr7139 -
Firslty - thanks for the code. Unfortunately - I cannot seem to get it to work and it throws an IOException when I try to run it. Perhaps I am doing something wrong (totally new to OpenOffice and its API.)
Here is how Im trying to save a Document as a PDF..
===================================================================
| Code: |
if W.Connect then
begin
if W.OpenDocument('F:\db\OpenOffice\test2.odt',False) then
W.SaveToPDF('F:\db\OpenOffice\test2.odt');
procedure TOOoWriter.SaveToPDF(FileName: string; HTMLSrc:boolean = false);
var
wProperties: variant;
s : string;
begin
if not (fConnected and fDocumentOpened) then
abort;
wProperties := VarArrayCreate([0, 0], varVariant);
if HTMLSrc then
wProperties[0] := MakePropertyValue('FilterName', 'writer_web_pdf_Export')
else
wProperties[0] := MakePropertyValue('FilterName', 'writer_pdf_Export');
s := StringReplace(FileName,'\','/', [rfReplaceAll]);
fDocument.StoreToURL('file:///'+ s, wProperties);
end;
|
===================================================================
Any help would be much appreciated..
Cheers..
Opp. |
|
| Back to top |
|
 |
sllimr7139 General User

Joined: 28 Jul 2005 Posts: 10
|
Posted: Sat Aug 13, 2005 6:52 pm Post subject: |
|
|
Hi Opp,
No problem, here is the fully finished class code that I'm currently using with no problems.
| Quote: | Hi sllimr7139 -
Firslty - thanks for the code. Unfortunately - I cannot seem to get it to work and it throws an IOException when I try to run it. Perhaps I am doing something wrong (totally new to OpenOffice and its API.)
Here is how Im trying to save a Document as a PDF..
<snip text>
Any help would be much appreciated.. |
| Code: | {================================================================================
Copyright (C) 1997-2005 Mills Enterprise
Unit : OpenOfficePDF
Purpose : This unit provides a single class to enabled the programmer to create a PDF
document through the OpenOffice.Org API. This unit is provided as freeware
please use at your own risk. This file can be found as a part of the rmControls
library
Date : 07-25-2005
Author : Ryan J. Mills
Version : 1.93
================================================================================}
unit OpenOfficePDF;
interface
uses ComObj, Variants, sysutils;
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]) , '_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', 'writer_pdf_Export');
wProperties[1] := MakePropertyValue('CompressionMode', '1');
wProperties[2] := MakePropertyValue('Pages', 'All');
wProperties[3] := MakePropertyValue('Overwrite', TRUE);
fDocument.StoreToURL('file:///'+ StringReplace(FileName, '\', '/', [rfIgnoreCase]), wProperties);
end;
end. |
To use this class use something similar to the following code:
| Code: |
procedure MakePDF(InFileName, OutFileName:string);
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;
except
on e:exception do
begin
response.content := 'PDF Document Error: '+e.message;
end;
end;
end;
|
Hope you find that helpful.
Ryan. |
|
| Back to top |
|
 |
Opp Newbie

Joined: 13 Aug 2005 Posts: 4
|
Posted: Sun Aug 14, 2005 4:30 am Post subject: |
|
|
Hi Ryan -
Thanks. Unfortunately I must be still doing something wrong . Still getting an IOException from OpenOffice.
Here is the way I am calling the methods..
| Code: |
begin
inFilename := 'F:\db\OpenOffice\test2.odt';
OutFilename :='F:\db\OpenOffice\test2.pdf';
MakePDF(infilename,OutFilename);
end
|
The only thing I am doing different (AFAIK) is replacing StringReplace with the D2005 equivelent function..
Filename := 'file:///'+ StringReplace(FileName, '\', '/', [rfIgnoreCase]);
fDocument.StoreToURL( s, wProperties);
The format of the resulting string is correct - As I have tried to open a document from a Browser (Opera) using the resulting string successfully.
I was unsure as to whether the OutputFilename should be the name of the required PDF file - but I have tried it in various forms - with the same result.
Thanks for your help.
Cheers..
Opp. |
|
| Back to top |
|
 |
sllimr7139 General User

Joined: 28 Jul 2005 Posts: 10
|
Posted: Sun Aug 14, 2005 5:26 am Post subject: |
|
|
Hi Opp,
Sorry for having to ask this but....
| Quote: | | Code: | Filename := 'file:///'+ StringReplace(FileName, '\', '/', [rfIgnoreCase]);
fDocument.StoreToURL( s, wProperties); |
|
If this is from your code and is what your doing, could it be that the variable 's' doesn't actually have anything in it?
Your assigning the new name back into 'Filename' but then trying to save the file from the 's' variable?
I can only tell you what I've done. I know my code works with 1.1.4 and the latest 2.0beta (1.9.122) that I've got installed. If you want me to look over your code, contact me via email (rmcontrols@mills-enterprise.ca) add an underscore ( _ ) to the front of the address, I'll take a look at it.
Ryan. |
|
| Back to top |
|
 |
Opp Newbie

Joined: 13 Aug 2005 Posts: 4
|
Posted: Mon Aug 15, 2005 1:55 pm Post subject: |
|
|
Hi (again) Ryan - guess you thought I had gone - no such luck . My ISP has been messing me about recelty and so no Internet for about 12 hours!
Anyway, if your offer is still godd - will take you up on having a look at my code . I have uploaded it to my site - here is URL..
http://www.op-code.co.uk/Remote/code.zip
Many thanks.
Cheers..
Opp. |
|
| Back to top |
|
 |
sllimr7139 General User

Joined: 28 Jul 2005 Posts: 10
|
Posted: Mon Aug 15, 2005 9:05 pm Post subject: |
|
|
Hi Opp,
Mea Culpa.
Please add the flag rfReplaceAll in both of the StringReplace function calls. I was replacing one of my homegrown functions with StringReplace and forgot to add that flag.
Once that is done the entire thing works with out an exception.
Sorry for the inconvienience.
Here is the full source, again, with the correct flags:
| Code: | {================================================================================
Copyright (C) 1997-2003 Mills Enterprise
Unit : OpenOfficePDF
Purpose : This unit provides a single class to enabled the programmer to create a PDF
document through the OpenOffice.Org API. This unit is provided as freeware
please use at your own risk. This file can be found as a part of the rmControls
library
Date : 07-25-2005
Author : Ryan J. Mills
Version : 1.93
================================================================================}
unit OpenOfficePDF;
interface
uses ComObj, Variants, sysutils;
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', '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;
end. |
Ryan. |
|
| Back to top |
|
 |
Opp Newbie

Joined: 13 Aug 2005 Posts: 4
|
Posted: Mon Aug 15, 2005 11:33 pm Post subject: |
|
|
Hey Ryan.. No problem at all .
Just tested it - and really pleased. Its working a treat. Being able to produce PDF files from OO Docs will be really useful.
And thanks for insight into the OO API (via Delphi.) Will go away now and start experimenting.
Cheers..
Opp. |
|
| Back to top |
|
 |
jjunchen Newbie

Joined: 27 Oct 2005 Posts: 1
|
Posted: Thu Oct 27, 2005 9:10 pm Post subject: Thanks you |
|
|
| I write java source for export pdf, as your method ok. |
|
| Back to top |
|
 |
floris_v Moderator


Joined: 12 Jul 2007 Posts: 4600 Location: Netherlands
|
Posted: Tue Jul 17, 2007 1:59 pm Post subject: |
|
|
That is totally awesome. Thanks a lot for that Delphi interface to OOo.  |
|
| Back to top |
|
 |
sebarnolds General User

Joined: 19 Oct 2009 Posts: 6
|
Posted: Mon Oct 19, 2009 11:06 pm Post subject: |
|
|
Hello.
I know this thread has been inactive for quite some time but I have a question about this code. I tried it in my application (Delphi 6, Windows XP with Open Office 3.0) and it seems that it always saves my file in ODT format (with the pdf extension).
I checked on the web and the filter name has not changed.
Any idea ?
Thanks,
Sebastien |
|
| 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
|