Java:打印数据表

时间:2017-01-18 16:34:25

标签: java javafx printing

我希望能够使用PrinterJob打印数据列表,但似乎PrinterJob仅打印Node,因此当我使用TableView并打印时它,首先它不打印所有元素,第二我不喜欢的设计。我的应用程序已经具有创建pdf表的功能(示例在这个问题的末尾显示),我的问题是如何打印这个pdf,这个打印过程对于POS打印机和普通打印机是一样的打印机?

enter image description here

修改

基于James_D 2的答案,我使用此代码进行打印:

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

至于createLogDocument如下:

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;

}

但是当我执行此代码时,我会java.io.IOExceptionNo file in print request。我犯了什么错误?

2 个答案:

答案 0 :(得分:1)

JavaFX打印API将无法打印您TableView中的所有数据。回想一下,表视图不会为表中的所有项创建单元格:仅为可见项目(未滚动到视图中的项目)创建单元格,并根据需要重复使用(例如,当用户时)滚动)。由于JavaFX打印API打印节点,并且不存在代表所有数据的节点,因此这根本不起作用。

由于您已经在表格中拥有数据的PDF表示,因此您可以使用标准javax.print API来打印PDF。 package documentation有关于如何执行此操作的详细信息,但您可以这样做:

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

如果您的PDF在内存中,而不是在文件中,并且您可以以byte[]的形式获取数据,则可以

byte[] pdfData = ... ;
DocFlavor pdfInFormat = DocFlavor.BYTE_ARRAY.PDF;
Doc myDoc = new SimpleDoc(pdfData, pdfInFormat, null);  

而不是如上所述使用该文件。

答案 1 :(得分:0)

我改变了我的createLog方法以返回一个字节数组,并且接缝工作正常。

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

至于createLogDocument方法:

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