Java: Spreadsheetgröße automatisch für Druck anpassen

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

danielandross
**
Beiträge: 24
Registriert: Do, 26.04.2007 16:07

Java: Spreadsheetgröße automatisch für Druck anpassen

Beitrag von danielandross »

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:

Code: Alles auswählen

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

Code: Alles auswählen

dispatcher.executeDispatch(document, ".uno:SelectAll", "", 0, Array())
dispatcher.executeDispatch(document, ".uno:DefinePrintArea", "", 0, Array())
in java umsetzen könnte. Wäre für jede Hilfe froh.
oseebass
*
Beiträge: 12
Registriert: Mi, 30.05.2007 13:42

dispatcher vs. api

Beitrag von oseebass »

hi,

das dispatcher-framework hilft dir hier wirklich nicht weiter.

besser hier: http://api.openoffice.org/docs/Develope ... rint_Areas

mit beispielcode.

hth,

gruß oliver
danielandross
**
Beiträge: 24
Registriert: Do, 26.04.2007 16:07

Beitrag von danielandross »

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?
moritz
*****
Beiträge: 216
Registriert: Mi, 20.10.2004 20:54

Druckbereiche, letzte Zelle

Beitrag von moritz »

Die folgenden Makros werden Dir weiterhelfen. Ermittelt werden die erste und letzte benutzte Zelle.

REM ***** BASIC *****
Sub Main
oDoc = ThisComponent
oSheet = oDoc.getSheets().getByIndex( 0 )

oLastCell = GetLastUsedCell( oSheet )
Print "Last cell is ", oLastCell.getRangeAddress().EndColumn, oLastCell.getRangeAddress().EndRow

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")

oSheet = ThisComponent.getSheets().getByName(regieSheetIndex)
oDoc = Thiscomponent
oDialogDruckForm.Execute()

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())


end sub
danielandross
**
Beiträge: 24
Registriert: Do, 26.04.2007 16:07

Beitrag von danielandross »

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:

Code: Alles auswählen

public void getLastUsedCellSpielwiese() {
		XSpreadsheetDocument xSpreadsheetDocument = (XSpreadsheetDocument) UnoRuntime
		.queryInterface(XSpreadsheetDocument.class, openDocument);
		XSpreadsheets spreadsheets=xSpreadsheetDocument.getSheets();
		String[] array=spreadsheets.getElementNames();
		
		int length=array.length;
		for(int i=0;i<length;i++){
			try {
				XSpreadsheet element=(XSpreadsheet)spreadsheets.getByName(array[i]);
				XSheetCellCursor cursor=element.createCursor();

//DIe nächsten beiden Interface Abfragen krachen
			XUsedAreaCursor xUsedAreaCursor=(XUsedAreaCursor)UnoRuntime
			.queryInterface(XUsedAreaCursor.class, cursor);
				XCellRangeAddressable  cellRangeAddress=(XCellRangeAddressable )UnoRuntime
				.queryInterface(XCellRangeAddressable .class, cursor);
			} catch (NoSuchElementException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (WrappedTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
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?
danielandross
**
Beiträge: 24
Registriert: Do, 26.04.2007 16:07

Beitrag von danielandross »

So jetzt bin ich soweit, dass ich Koordinaten auslesen kann. Wie mache ich das jetzt aber das es mir die letzte beschriebene reihe anvisiert?

Code: Alles auswählen

		XSpreadsheetDocument xSpreadsheetDocument = (XSpreadsheetDocument) UnoRuntime
				.queryInterface(XSpreadsheetDocument.class, openDocument);
		XSpreadsheets spreadsheets = xSpreadsheetDocument.getSheets();

		XIndexAccess xSheetsIA = (XIndexAccess) UnoRuntime.queryInterface(
				XIndexAccess.class, spreadsheets);
		try {
			XSpreadsheet xs = (XSpreadsheet) UnoRuntime.queryInterface(
					XSpreadsheet.class, xSheetsIA.getByIndex(0));
			XSheetCellCursor cursor = xs.createCursor();
			XCellRangeAddressable cellRangeAddress = (XCellRangeAddressable) UnoRuntime
					.queryInterface(XCellRangeAddressable.class, cursor);
			CellRangeAddress address = cellRangeAddress.getRangeAddress();
			int sRow = address.StartRow;
			int sCol = address.StartColumn;
			int eRow = address.EndRow;
			int eCol = address.EndColumn;
			System.out.println("sRow: " + sRow);
			System.out.println("sCol: " + sCol);
			System.out.println("eRow: " + eRow);
			System.out.println("eCol: " + eCol);
danielandross
**
Beiträge: 24
Registriert: Do, 26.04.2007 16:07

Re: Java: Spreadsheetgröße automatisch für Druck anpassen

Beitrag von danielandross »

Code: Alles auswählen

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.
Antworten