Moin,
ich möchte eine FXML(Vorlage) laden, diese mit Daten befüllen und dann drucken.
Das klappt leider nicht 100%ig und ich hatte gehofft jemand hat einen Rat für mich.
Das ist meine FXML-Vorlage, erstellt mit dem SceneBuilder.
Das ist meine Druck-Klasse. Diese soll Vorlage entsprechend dem Datentyp und der übergebenen Ausrichtung laden und drucken.
Der erstellte Druckauftrag hat dann auch wie gewünscht die entsprechende Anzahl Seiten und dies mit der entsprechenden Vorlage.
Allerdings wird nur Seite 1 korrekt bearbeitet.
Seite 2 und alle weiteren werden nicht skaliert auf das Druckformat.
Und wenn ich einen Auftrag mit z.B. 25 Listeneinträgen übergebe, ist Seite 2 leer (allerdings nur die Datenzeilen der Tabelle, die Überschriften sind vorhanden), obwohl die Daten korrekt in die Tabelle eingefügt wurden.
Gibt es da einen Trick um mehrseitig zu drucken?
ich möchte eine FXML(Vorlage) laden, diese mit Daten befüllen und dann drucken.
Das klappt leider nicht 100%ig und ich hatte gehofft jemand hat einen Rat für mich.
Java:
<AnchorPane id="AnchorPane" fx:id="master" maxHeight="570.0" maxWidth="800.0" minHeight="570.0" minWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox fx:id="page" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: rgb(247, 248, 249);" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<HBox fx:id="header" prefHeight="50.0" prefWidth="600.0">
<children>
<Label id="label_title" fx:id="label_title" alignment="BASELINE_CENTER" prefHeight="50.0" prefWidth="800.0" text="Titel">
<font>
<Font name="System Bold" size="24.0" />
</font>
</Label>
</children>
</HBox>
<VBox fx:id="content" prefHeight="500.0" prefWidth="800.0">
<children>
<TableView id="table_content" fx:id="table_content" prefHeight="500.0" prefWidth="800.0" VBox.vgrow="NEVER" />
</children>
</VBox>
<HBox fx:id="footer" alignment="CENTER_RIGHT" prefHeight="20.0" prefWidth="800.0" spacing="20.0">
<children>
<Label id="label_date" fx:id="label_date" text="Stand: dd.mm.yyyy" />
<Label id="label_page" fx:id="label_page" text="Seite n / n" />
</children>
<padding>
<Insets left="5.0" right="5.0" />
</padding>
</HBox>
</children>
</VBox>
</children>
</AnchorPane>
Java:
package de.onlinewartungsplaner.jowp.printing;
import de.onlinewartungsplaner.jowp.JOWP;
import de.onlinewartungsplaner.jowp.viewmodel.vmMaterial;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.print.JobSettings;
import javafx.print.PageLayout;
import javafx.print.PageOrientation;
import javafx.print.Paper;
import javafx.print.Printer;
import javafx.print.PrinterJob;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.transform.Scale;
/**
*
* @author BOBmoraine
*/
public class Printing {
final JOWP importMainClass = JOWP.getInstance();
private PageOrientation format = null;
private final ObservableList list;
private AnchorPane report;
private int pagesSum = 1; //Anzahl Seiten gesammt
private PrinterJob printerJob;
private JobSettings jobSettings;
private Printer printer;
private PageLayout pageLayout;
private int entrysPerPage = 8; //Einträge pro Seite
/**
* Rahmenbedingungen für Druckauftrag einstellen
* @param List Gesammtliste der zu druckenden Daten
* @param PageOrientation Ausrichtung der Seite
* @param rowsPerPage Anzahl der Dateneinträge pro Seite
*/
public Printing(ObservableList List, PageOrientation PageOrientation, int rowsPerPage){
this.list = FXCollections.observableArrayList(List);
this.format = PageOrientation;
this.entrysPerPage = rowsPerPage;
double zwischenwert = Math.ceil(list.size()/(double)this.entrysPerPage);
pagesSum = (int)zwischenwert;
// Erstellung des Druck-Jobs
printerJob = PrinterJob.createPrinterJob();
jobSettings = printerJob.getJobSettings();
printer = Printer.getDefaultPrinter();
pageLayout = printer.createPageLayout(Paper.A4, this.format, Printer.MarginType.HARDWARE_MINIMUM);
jobSettings.setPageLayout(pageLayout);
}
/**
* Drucken
*/
public void start(){
if(list.size()>=1){
//Druckauswahl öffnen und daten verarbeiten
if (printerJob.showPrintDialog(importMainClass.getPrimaryStage().getOwner())){
formatPrintingData();
printerJob.endJob();
}
}
}
/**
* Nodes in Vorlage mit Daten füllen
*/
private void formatPrintingData() {
if(list.get(0) instanceof vmMaterial ){
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXML_A4_Landscape.fxml"));
try {
report = null;
report = (AnchorPane) loader.load();
//TODO report.getStylesheets().add(getClass().getResource("printing/FXML_A4_Landscape.css").toExternalForm());
}
catch (IOException e) {
e.printStackTrace();
}
Label title = (Label) report.lookup("#label_title");
title.setText("Überschrift");
//footer-daten einstellen
Label date = (Label) report.lookup("#label_date");
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMANY);
String output = formatter.format(new Date());
date.setText("Druckdatum: " + output);
Label page = (Label) report.lookup("#label_page");
ObservableList<PrintingTableDataStorage> listOfTableData = FXCollections.observableArrayList(); //list for table
//seiten durchlaufen
for(int i = 1; i<= pagesSum; i++){
listOfTableData.clear();
//seitendaten durchlaufen
for(int iD = i*entrysPerPage-entrysPerPage; iD<i*entrysPerPage; iD++){
if(iD<list.size()){
vmMaterial rowEntry = (vmMaterial)list.get(iD);
listOfTableData.add(new PrintingTableDataStorage(rowEntry.getMaterialStatusName(), rowEntry.getMaterialItemNameForSummary(), rowEntry.getMaterialNotiz()));
//Testausgabe, alle Daten werden Seitenweise richtig übergeben
System.out.println(rowEntry.getMaterialID() + "::" + rowEntry.getMaterialItemNameForSummary());
}
}
TableView<PrintingTableDataStorage> table = (TableView) report.lookup("#table_content");
table.getColumns().clear();
table.setItems(listOfTableData);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn column01 = new TableColumn();
column01.setMaxWidth((report.getMinWidth()-3)/3);
column01.setMinWidth((report.getMinWidth()-3)/3);
column01.setText("Status");
column01.setCellValueFactory(new PropertyValueFactory<>("column01Data"));
TableColumn column02 = new TableColumn();
column02.setMaxWidth((report.getMinWidth()-3)/3);
column02.setMinWidth((report.getMinWidth()-3)/3);
column02.setText("Summary");
column02.setCellValueFactory(new PropertyValueFactory<>("column02Data"));
TableColumn column03 = new TableColumn();
column03.setMaxWidth((report.getMinWidth()-3)/3);
column03.setMinWidth((report.getMinWidth()-3)/3);
column03.setText("Notiz");
column03.setCellValueFactory(new PropertyValueFactory<>("column03Data"));
table.getColumns().addAll(column01, column02, column03);
page.setText("Seiten " + i + "/" + pagesSum);
//vorlage skalieren
double scaleX = pageLayout.getPrintableWidth() / report.getMinWidth();
double scaleY = pageLayout.getPrintableHeight() / report.getMinHeight();
report.getTransforms().add(new Scale(scaleX, scaleY));
waitForDone(report);
}
}
}
/**
* PrintPage
* @param reportIn Node to print
*/
public synchronized void waitForDone(AnchorPane reportIn) {
try {
boolean jobDone = printerJob.printPage(reportIn);
while (!jobDone) {
wait();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Der erstellte Druckauftrag hat dann auch wie gewünscht die entsprechende Anzahl Seiten und dies mit der entsprechenden Vorlage.
Allerdings wird nur Seite 1 korrekt bearbeitet.
Seite 2 und alle weiteren werden nicht skaliert auf das Druckformat.
Und wenn ich einen Auftrag mit z.B. 25 Listeneinträgen übergebe, ist Seite 2 leer (allerdings nur die Datenzeilen der Tabelle, die Überschriften sind vorhanden), obwohl die Daten korrekt in die Tabelle eingefügt wurden.
Gibt es da einen Trick um mehrseitig zu drucken?
Java:
//listOfMaterial eine Liste mit 25 Einträgen
Printing newPrinting = new Printing(listOfMaterial, PageOrientation.LANDSCAPE, 10);
newPrinting.start();