Reputation: 2093
I want to be able to print a list of data using PrinterJob
, but it seems PrinterJob
prints only Node
s, so when I use a TableView
and print it, first it does not print all elements, second I do not like the design. My application already has a functionality of creating pdf tables (a sample is show at the end of this question) and my question is how can I print this pdf, and this proccess of printing is it the same for a POS printer as for a normal printer?
EDIT
Based on the answer of James_D 2, I used this code to print:
Document document = createLogDocument(items);
if (document != null) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter.getInstance(document, byteArrayOutputStream);
byte[] pdfData = byteArrayOutputStream.toByteArray();
DocFlavor pdfInFormat = DocFlavor.BYTE_ARRAY.PDF;
Doc myDoc = new SimpleDoc(pdfData, pdfInFormat, null);
PrintRequestAttributeSet set = new HashPrintRequestAttributeSet();
PrintService[] services = PrintServiceLookup.lookupPrintServices(pdfInFormat, set);
if (services.length > 0) {
PrintService service = ServiceUI.printDialog(null, 50, 50, services, services[0], null, set);
DocPrintJob job = service.createPrintJob();
job.print(myDoc, set);
}
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (PrintException e) {
e.printStackTrace();
}
as for the createLogDocument
it's as follows:
private static Document createLogDocument(List<Log> logs) throws DocumentException {
Document document = new Document();
document.open();
PdfPTable table = new PdfPTable((new float[]{10, 20, 50, 10, 10}));
table.setWidthPercentage(100);
table.setSpacingAfter(20);
table.setSpacingAfter(20);
PdfPTable header = new PdfPTable((new float[]{10, 20, 50, 10, 10}));
header.setWidthPercentage(100);
header.setSpacingAfter(20);
header.setSpacingBefore(20);
PdfPCell cell = null;
setHeaderCell(cell, "Date", header);
setHeaderCell(cell, "Type", header);
setHeaderCell(cell, "Details", header);
setHeaderCell(cell, "Client", header);
setHeaderCell(cell, "Employee", header);
for (Log log : logs) {
setNormalCell(cell, log.getDate().toString(), table);
setNormalCell(cell, log.getDescription().split(":")[0], table);
setNormalCell(cell, log.getDescription().split(":")[1], table);
setNormalCell(cell, log.getClient().getName(), table);
setNormalCell(cell, log.getEmployee().getName(), table);
}
boolean b = true;
for (PdfPRow r : table.getRows()) {
for (PdfPCell c : r.getCells()) {
c.setBackgroundColor(b ? BaseColor.LIGHT_GRAY : BaseColor.WHITE);
}
b = !b;
}
document.add(header);
document.add(table);
document.close();
return document;
}
But when I exectue this code I get a java.io.IOException
saying that No file in print request
. What mistake am I making?
Upvotes: 1
Views: 1050
Reputation: 2093
Well I changed my createLog
method to return a byte array, and it seams to work fine.
try {
byte[] pdfData = createLogDocument(items);
if (pdfData.length != 0) {
DocFlavor pdfInFormat = DocFlavor.BYTE_ARRAY.PDF;
Doc myDoc = new SimpleDoc(pdfData, pdfInFormat, null);
PrintRequestAttributeSet set = new HashPrintRequestAttributeSet();
PrintService[] services = PrintServiceLookup.lookupPrintServices(pdfInFormat, set);
if (services.length > 0) {
PrintService service = ServiceUI.printDialog(null, 50, 50, services, services[0], null, set);
if (service != null) {
DocPrintJob job = service.createPrintJob();
job.print(myDoc, set);
}
}
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (PrintException e) {
e.printStackTrace();
}
As for the createLogDocument
method:
private static byte[] createLogDocument(List<Log> logs) throws DocumentException {
Document document = new Document();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter.getInstance(document, byteArrayOutputStream);
document.open();
//Fill the document with info
document.close();
byte[] pdfData = byteArrayOutputStream.toByteArray();
return pdfData;
}
Upvotes: 0
Reputation: 209225
The JavaFX print API will not be able to print your TableView
will all the data in it. Recall that table views do not create cells for all of the items in the table: cells are only created for visible items (those not scrolled out of the view) and are reused as needed (e.g. when the user scrolls). Since the JavaFX print API prints nodes, and no nodes exist representing all of the data, then this simply won't work.
Since you already have a PDF representation of the data in your table, you can use the standard javax.print
API to print the PDF. The package documentation has details on how to do this, but in brief you would do:
FileInputStream pdfStream;
try {
pdfStream = new FileInputStream("file.pdf");
} catch (FileNotFoundException ffne) {
ffne.printStackTrace();
}
if (pdfStream == null) {
return;
}
DocFlavor pdfInFormat = DocFlavor.INPUT_STREAM.PDF;
Doc myDoc = new SimpleDoc(pdfStream, pdfInFormat, null);
PrintRequestAttributeSet aset =
new HashPrintRequestAttributeSet();
PrintService service =
PrintServiceLookup.lookupDefaultPrintService(psInFormat, aset);
if (service != null) {
DocPrintJob job = service.createPrintJob();
try {
job.print(myDoc, aset);
} catch (PrintException pe) {
pe.printStackTrace();
}
}
If your PDF is in memory, rather than in a file, and you can get the data in the form of a byte[]
, you can do
byte[] pdfData = ... ;
DocFlavor pdfInFormat = DocFlavor.BYTE_ARRAY.PDF;
Doc myDoc = new SimpleDoc(pdfData, pdfInFormat, null);
instead of working with the file as above.
Upvotes: 1