3

Here there are an example of saving an OpenOffice file to PDF. I'm using similar code to save Calc files to PDF. (It's enough to change the property writer_pdf_Export to calc_pdf_Export.)

Unfortunately, the code doesn't take into account the print area defined in the original file.

How can I do that?

Community
  • 1
  • 1
  • It should be enough to use the [`Selection`](http://wiki.services.openoffice.org/wiki/API/Tutorials/PDF_export#General_properties) property of the PDF filter data where you specify the cell range to be printed. – TLama May 21 '12 at 19:46

2 Answers2

2

Extending my previous code (which is not as clean as it could be) I would try something like this (note I haven't tested it yet). The third parameter specifies the exported range as TRect variable:

procedure ExportCalcRangeToPDF(const ASourceFileURL, ATargetFileURL: string;
  ASheetIndex: Integer; ARange: TRect);
var
  CellRange: Variant;
  StarOffice: Variant;
  StarDesktop: Variant;
  StarDocument: Variant;
  FilterParams: Variant;
  ExportParams: Variant;
  ExportObject: Variant;

  function CreateProperty(const AName: AnsiString; const AValue: Variant): Variant;
  begin
    Result := StarOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
    Result.Name := AName;
    Result.Value := AValue;
  end;

begin
  StarOffice := CreateOleObject('com.sun.star.ServiceManager');
  StarDesktop := StarOffice.CreateInstance('com.sun.star.frame.Desktop');

  FilterParams := VarArrayCreate([0, 0], varVariant);
  FilterParams[0] := CreateProperty('Hidden', True);

  StarDocument := StarDesktop.LoadComponentFromURL(ASourceFileURL, '_blank', 0,
    FilterParams);
  CellRange := StarDocument.Sheets.getByIndex(ASheetIndex).getCellRangeByPosition(
    ARange.Left, ARange.Top, ARange.Right, ARange.Bottom);

  ExportParams := VarArrayCreate([0, 0], varVariant);
  ExportParams[0] := CreateProperty('Selection', CellRange);

  ExportObject := StarOffice.Bridge_GetValueObject;
  ExportObject.Set('[]com.sun.star.beans.PropertyValue', ExportParams);

  FilterParams := VarArrayCreate([0, 1], varVariant);
  FilterParams[0] := CreateProperty('FilterName', AnsiString('calc_pdf_Export'));
  FilterParams[1] := CreateProperty('FilterData', ExportObject);

  StarDocument.StoreToURL(ATargetFileURL, FilterParams);

  StarDocument.Close(True);
  StarDesktop.Terminate;

  StarDocument := Unassigned;
  StarDesktop := Unassigned;
  StarOffice := Unassigned;
end;    

procedure TForm1.Button1Click(Sender: TObject);
begin
  ExportCalcRangeToPDF(
    'file:///C:/SourceFile.ods',
    'file:///C:/TargetFile.pdf',
    0,
    Rect(1, 1, 2, 2)
  );
end;
TLama
  • 75,147
  • 17
  • 214
  • 392
  • All seems to be about the [`Selection`](http://wiki.services.openoffice.org/wiki/API/Tutorials/PDF_export#General_properties) property of the PDF filter, you need to specify the [`XCellRange`](http://www.openoffice.org/api/docs/common/ref/com/sun/star/table/XCellRange.html) for what you want to export. Leave here some feedback, please. If it works or not. I'll make a review for this, because it's not so good keep there a hardcoded sheet name for getting the cell range. – TLama May 22 '12 at 09:55
  • 1
    It works. Now I need the method to fill rect variable with the print area defined in the original file. I'm on it, thank you very much for your help. – user1407913 May 22 '12 at 12:12
1

To get the print area of the spreadsheet, I do this. (Improvable, of course).

  ...
  Sheet: Variant;
  PrintAreas: Variant;
  ...

  ...
  Sheet := StarDocument.Sheets.getByIndex(0); // get the first sheet
  PrintAreas := Sheet.getPrintAreas; // get print areas

  CellRange := Sheet.getCellRangeByPosition(PrintAreas[0].StartColumn,
        PrintAreas[0].StartRow, PrintAreas[0].EndColumn,
        PrintAreas[0].EndRow); // Get range of the first print area
  ...
  • +1, maybe you might use `PrintArea := Sheet.getPrintAreas[0];` and use it like `getCellRangeByPosition(PrintArea.StartColumn, ...` ;-) – TLama May 23 '12 at 08:33