简体   繁体   中英

Java: Print table of data

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?

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 (eg 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.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM