Hallo,
ich versuche gerade einen Weg zu finden meine aus einem Open Office Spreadsheet gewonnenen pdfs künftig so erstellen zu lassen, dass mein Programm selber die seite so anpasst dass mein dokument perfekt darauf passt (und nicht teile einer tabelle auf der nächsten pdf seite angezeigt werden). Folgendes OpenOffice-Makro setzt mein Vorhaben um:
sub Seiteanpassen
rem ----------------------------------------------------------------------
rem define variables
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:SelectAll", "", 0, Array())
rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:DefinePrintArea", "", 0, Array())
rem ----------------------------------------------------------------------
dim args3(0) as new com.sun.star.beans.PropertyValue
args3(0).Name = "ToPoint"
args3(0).Value = "$F$9"
dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args3())
rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:PageFormatDialog", "", 0, Array())
rem ----------------------------------------------------------------------
dim args5(1) as new com.sun.star.beans.PropertyValue
args5(0).Name = "Copies"
args5(0).Value = 1
args5(1).Name = "Collate"
args5(1).Value = false
dispatcher.executeDispatch(document, ".uno:Print", "", 0, args5())
end sub
Der Spreadsheet kann geöffnet werden und auch die umwandlung in PDF läuft schon.
Mir fehlt leider noch generell das OOo-SDK Verständnis dass ich die beiden Zeilen:
- alles markieren
- als druckbereich setzen
Ok diese getPrintAreas() Methode aus dem Interface XPrintAreas hört sich ja schonmal gut an, leider ist das nur ein Interface und das eigentlich Problem ist die implementierung dieser Methode. Dann könnte ich ihm ja über ein Size Objekte breite und höhe übergeben und das Format so perfekt anpassen. Habt ihr ne idee wie das gehen könnte?
edit: Wie gesagt geht es nur darum die Positionen der "maximalen" Zellen zu berechnen, also die mit der maximalen x-achse Position und die mit der maximalen y-achse Position. Deshalb kann man ja hergehen und alle zellen vergleichen(wenns sein muss) und sich immer den höchsten Wert merken. Jetzt ist nur die Frage wie gehe ich alle Zellen durch (Index?) und wie frage ich deren Poitionen ab?
oFirstCell = GetFirstUsedCell( oSheet )
Print "First cell is ", oFirstCell.getRangeAddress().EndColumn, oFirstCell.getRangeAddress().EndRow
End Sub
Function GetLastUsedCell( oSheet As com.sun.star.sheet.Spreadsheet ) As com.sun.star.sheet.SheetCell
' The Spreadsheet interface XSpreadsheet has method createCursor(),
' which returns a SheetCellCursor.
oCellCursor = oSheet.createCursor()
' The SheetCellCursor has interface XUsedAreaCursor, which has method gotoEndOfUsedArea().
oCellCursor.gotoEndOfUsedArea( False )
' The SheetCellCursor includes service SheetCellRange which has interface XCellRangeAddressable
' which has method getRangeAddress(), which returns a struct com.sun.star.table.CellRangeAddress.
tCellRangeAddress = oCellCursor.getRangeAddress()
' Get the last used cell on the spreadsheet.
oCell = oSheet.getCellByPosition( tCellRangeAddress.EndColumn, tCellRangeAddress.EndRow )
GetLastUsedCell = oCell
end function
Function GetFirstUsedCell( oSheet As com.sun.star.sheet.Spreadsheet ) As com.sun.star.sheet.SheetCell
' The Spreadsheet interface XSpreadsheet has method createCursor(),
' which returns a SheetCellCursor.
oCellCursor = oSheet.createCursor()
' The SheetCellCursor has interface XUsedAreaCursor, which has method gotoStartOfUsedArea().
oCellCursor.gotoStartOfUsedArea( False )
' The SheetCellCursor includes service SheetCellRange which has interface XCellRangeAddressable
' which has method getRangeAddress(), which returns a struct com.sun.star.table.CellRangeAddress.
tCellRangeAddress = oCellCursor.getRangeAddress()
' Get the first used cell on the spreadsheet.
oCell = oSheet.getCellByPosition( tCellRangeAddress.EndColumn, tCellRangeAddress.EndRow )
GetFirstUsedCell = oCell
end function
Und hier noch Beispiele für das arbeiten mit Druckbereichen
sub Drucken_benannte_Bereiche
dim i As Integer
Dim oSheet As Object
Dim oBenannterBereich As Object
Dim oDoc as object
Dim selArea(0) as new com.sun.star.table.CellRangeAddress
Dim DruckEigenschaften(0) As New com.sun.star.beans.PropertyValue
Dim sURL As string
const sDateiText ="Adobe pdf- Dateien (*.pdf)"
const sDateiJoker = "*.pdf"
oDialogDruckForm = CreateUnoDialog(DialogLibraries.Standard.fmDruck)
Dialoglibraries.Loadlibrary("Standard")
for i = 0 to thisComponent.NamedRanges.Count-1
if left$(thisComponent.NamedRanges.ElementNames(i),6) = "regieB" then
oBenannterBereich = thisComponent.NamedRanges.GetByIndex(i)
'msgbox "Drucke " & thisComponent.NamedRanges.ElementNames(i)
selArea(0).StartColumn = oBenannterBereich.ReferredCells.RangeAddress.StartColumn
selArea(0).StartRow = oBenannterBereich.ReferredCells.RangeAddress.StartRow
selArea(0).EndColumn = oBenannterBereich.ReferredCells.RangeAddress.EndColumn
selArea(0).EndRow = oBenannterBereich.ReferredCells.RangeAddress.EndRow
oSheet.setPrintareas(selArea())
if boDruck = True then
oDoc.Print(Array())
'xray oBenannterBereich
else
sUrlVorgabe= "Arbeitszeitbericht " & oBenannterBereich.getReferredCells.getCellByPosition(3,3).string & " von " & oBenannterBereich.getReferredCells.getCellByPosition(7,5).string & " bis " & oBenannterBereich.getReferredCells.getCellByPosition(7,7).string & ".pdf"
DruckEigenschaften(0).Name="FilterName"
DruckEigenschaften(0).Value = "writer_pdf_Export"
SaveFileDialog(sURL, sDateiText, sDateiJoker, sUrlVorgabe)
oDoc.storetoUrl(sUrl,DruckEigenschaften())
end if
Druckbereich_aus
end if
next
end Sub
Sub Druckbereich_Ein (sSht$, nStC&, nStR&, nEndC&, nEndR&)
'------------------------------------------------------------------
Dim selArea(0) as new com.sun.star.table.CellRangeAddress
Dim oDoc as object
Dim oSheet as object
Dim oSheets
Dim i%
oDoc = Thiscomponent
oSheets = ThisComponent.Sheets
oSheet = ThisComponent.currentSelection.getSpreadsheet()
oSheet.setPrintareas(array())
selArea(0).StartColumn = 1
selArea(0).StartRow = 0
selArea(0).EndColumn = 12
selArea(0).EndRow = 46
oSheet=ThisComponent.currentSelection.getSpreadsheet()
oSheet.setPrintareas(selArea())
oDoc.Print(Array())
End Sub
REM++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM Hier wird der Druckbereich wieder gelöscht.
REM++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sub Druckbereich_aus
rem ----------------------------------------------------------------------
rem define variables
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:DeletePrintArea", "", 0, Array())
Hallo, dank für den Code jetzt habe ich schonmal ne grobe Vorstellung. iCh muss das ganze in Java implementieren und bin dabei gerade auf ein paar probleme gestoßen. Mein Code bisher:
Bei den beiden letzten Interface Abfragen wirft er eine java.lang.ClassCastException. Ich kenne mich nicht gut mit dem OpenOffice aus und weiß nicht was daran falsch ist. Findet jemand den Fehler in den beiden Zeilen?
com.sun.star.sheet.XUsedAreaCursor xUsedCursor = (com.sun.star.sheet.XUsedAreaCursor) UnoRuntime
.queryInterface(com.sun.star.sheet.XUsedAreaCursor.class, xCursor);
xUsedCursor.gotoStartOfUsedArea(false);
xUsedCursor.gotoEndOfUsedArea(true);
CellRangeAddress cellAddress=getCellRangeAddressCellRangeAddress(xCursor, true);
int countRowsNeeded=cellAddress.EndRow-cellAddress.StartRow;
int countColumnsNeeded=cellAddress.EndColumn-cellAddress.StartColumn;
Mit diesem Code bekomme ich die Spannbreite und Höhe die ich drucken möchte. Wenn mir jetzt noch jemand sagt die ich die breite und höhe einer Zeile/ Spalte bekomme kann ich die addieren und zu einem Size zusammenfassen, was mein Vorhaben komplettieren würde.