2017-01-18 2 views
0

Я хочу, чтобы иметь возможность распечатать список данных, используя PrinterJob, но это, кажется, PrinterJob печатает только Node с, так что, когда я использую TableView и распечатать его, сначала он не печатает все элементы, второй мне не нравится дизайн. Мое приложение уже имеет функциональность создания pdf-таблиц (образец показан в конце этого вопроса), и мой вопрос заключается в том, как я могу распечатать этот pdf-файл, и этот процесс печати одинаковый для POS-принтера, как для обычного принтер?Java: Печать таблицы данных

enter image description here

EDIT

На основании ответа 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; 

}

Но когда я exectue этого кода я получаю java.io.IOException сказать, что No file in print request. Какую ошибку я делаю?

ответ

1

API печати JavaFX не сможет печатать TableView все данные в нем. Напомним, что представления таблиц не создают ячейки для всех элементов в таблице: ячейки создаются только для видны элементов (те, которые не прокручиваются из представления) и повторно используются по мере необходимости (например, когда пользователь прокручивает). Поскольку API печати JavaFX печатает узлы, и ни один из узлов не представляет всех данных, это просто не сработает.

Поскольку у вас уже есть PDF-представление данных в вашей таблице, вы можете использовать стандартный API javax.print для печати 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); 

вместо того, чтобы работать с файлом, как указано выше.

+0

Будет ли эта работа для обоих принтеров (я имею в виду POS и нормально), так как я не являюсь владельцем ККМ, чтобы попробовать это? –

+1

@ Ayoub.A У меня нет ни одного ... Это должно быть. Я могу действительно ссылаться только на документацию. Вы можете получить все принтеры («службы печати»), способные печатать документ, используя «PrintServiceLookup.lookupPrintServices (...)», а также запрашивать или изменять аспекты принтера с помощью 'PrintService.getAttributes()', как только у вас есть доступ к соответствующий принтер. Но у меня нет возможности тестировать ... –

+0

Не могли бы вы показать мне, как показать диалог печати, я не могу найти способ сделать это. спасибо –

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

 Смежные вопросы

  • Нет связанных вопросов^_^