我正在开发一个打印文件的JAVA程序。 我需要知道打印机何时完成打印文件,我发现这个简单的代码很有意思:
import javax.print.*;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterStateReason;
import javax.print.attribute.standard.PrinterStateReasons;
import javax.print.attribute.standard.Severity;
import javax.print.event.*;
import java.awt.*;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.*;
import java.util.Set;
/**
* PrintTest
*/
public class PrintTest implements PrintServiceAttributeListener,PrintJobListener,Doc, Printable, PrintJobAttributeListener {
private static final transient String TEXT = "12345";
public static void main(String[] args) {
PrintTest test = new PrintTest();
test.checkPrinters();
}
public void checkPrinters() {
Thread newThread = new Thread(new Runnable() {
public void run() {
PrintService ps = PrinterJob.getPrinterJob().getPrintService();
DocFlavor[] myFlavors = ps.getSupportedDocFlavors();
ps.addPrintServiceAttributeListener(PrintTest.this);
DocPrintJob docJob = ps.createPrintJob();
docJob.addPrintJobAttributeListener(PrintTest.this, null);
docJob.addPrintJobListener(PrintTest.this);
try {
docJob.print(PrintTest.this,null);
}
catch (PrintException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
} });
newThread.start();
/**
PrintServiceAttributeSet attSet = ps.getAttributes();
PrinterStateReasons psr = ps.getAttribute(PrinterStateReasons.class);
if (psr != null) {
Set<PrinterStateReason> errors = psr.printerStateReasonSet(Severity.REPORT);
for (PrinterStateReason reason : errors)
System.out.printf(" Reason : %s",reason.getName());
System.out.println();
} */
}
public void attributeUpdate(PrintServiceAttributeEvent psae) {
System.out.println(psae.getAttributes());
}
public void printDataTransferCompleted(PrintJobEvent pje) {
System.out.println("Transfer completed");
}
public void printJobCompleted(PrintJobEvent pje) {
System.out.println("Completed");
}
public void printJobFailed(PrintJobEvent pje) {
System.out.println("Failed");
PrinterStateReasons psr = pje.getPrintJob().getPrintService().getAttribute(PrinterStateReasons.class);
if (psr != null) {
Set<PrinterStateReason> errors = psr.printerStateReasonSet(Severity.REPORT);
for (PrinterStateReason reason : errors)
System.out.printf(" Reason : %s",reason.getName());
System.out.println();
}
}
public void printJobCanceled(PrintJobEvent pje) {
System.out.println("Canceled");
}
public void printJobNoMoreEvents(PrintJobEvent pje) {
System.out.println("No more events");
}
public void printJobRequiresAttention(PrintJobEvent pje) {
System.out.println("Job requires attention");
PrinterStateReasons psr = pje.getPrintJob().getPrintService().getAttribute(PrinterStateReasons.class);
if (psr != null) {
Set<PrinterStateReason> errors = psr.printerStateReasonSet(Severity.REPORT);
for (PrinterStateReason reason : errors)
System.out.printf(" Reason : %s",reason.getName());
System.out.println();
}
}
public DocFlavor getDocFlavor() {
return DocFlavor.SERVICE_FORMATTED.PRINTABLE; //To change body of implemented methods use File | Settings | File Templates.
}
public Object getPrintData() throws IOException {
return this;
}
public DocAttributeSet getAttributes() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public Reader getReaderForText() throws IOException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public InputStream getStreamForBytes() throws IOException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
return pageIndex == 0 ? PAGE_EXISTS : NO_SUCH_PAGE; //To change body of implemented methods use File | Settings | File Templates.
}
public void attributeUpdate(PrintJobAttributeEvent pjae) {
System.out.println("Look out");
}
}
所以,我感兴趣的方法是:
public void printJobCompleted(PrintJobEvent pje) {
System.out.println("Completed");
}
但它对我不起作用。问题是打印机不支持这种类型的代码。有人能告诉我一个支持这段代码的打印机型号吗?
答案 0 :(得分:0)
查看示例代码here:
您似乎需要实施PrintJobAdapter
。相关位是:
package com.your.package;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;
public class DetermineThatPrintJobHasFinished {
public static void main(String[] args) throws Exception {
//... see example in link
// Locate the default print service for this environment.
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
// Create and return a PrintJob capable of handling data from
// any of the supported document flavors.
DocPrintJob printJob = service.createPrintJob();
// register a listener to get notified when the job is complete
JobCompleteMonitor monitor = new JobCompleteMonitor();
printJob.addPrintJobListener(monitor);
// Construct a SimpleDoc with the specified print data, doc flavor and doc attribute set.
Doc doc = new SimpleDoc(is, flavor, null);
// Print a document with the specified job attributes.
printJob.print(doc, null);
monitor.waitForJobCompletion();
is.close();
}
private static class JobCompleteMonitor extends PrintJobAdapter {
private boolean completed = false;
@Override
public void printJobCanceled(PrintJobEvent pje) {
signalCompletion();
}
@Override
public void printJobCompleted(PrintJobEvent pje) {
signalCompletion();
}
@Override
public void printJobFailed(PrintJobEvent pje) {
signalCompletion();
}
@Override
public void printJobNoMoreEvents(PrintJobEvent pje) {
signalCompletion();
}
private void signalCompletion() {
synchronized (JobCompleteMonitor.this) {
completed = true;
JobCompleteMonitor.this.notify();
}
}
public synchronized void waitForJobCompletion() {
try {
while (!completed) {
wait();
}
} catch (InterruptedException e) {
}
}
}
}
答案 1 :(得分:0)
效率不是最好的,但是您可以等到属性:'queued-job-count'等于零:
public final static void waitEndJobs(final PrintService printService) throws InterruptedException {
int queue = 1;
while (queue != 0) {
final AttributeSet attributes = printService.getAttributes();
final Attribute a = Arrays.stream(attributes.toArray())//
.filter(o -> o.getName().equalsIgnoreCase("queued-job-count"))//
.findFirst()//
.orElse(null);
queue = Integer.parseInt(attributes.get(a.getClass()).toString());
Thread.sleep(5000);
}
}
答案 2 :(得分:0)
就我而言,Rx或Project Reactor可以很好地帮助使用此旧的Java打印机api。我最近也遇到了这个问题,目前我已经完成了下一版本。也许会对某人有帮助
首先,如果您使用的是pdfbox,那么
from django.db import models
# Create your models here.
class Subscriber(models.Model):
email = models.EmailField(max_length=75,)
def __str__(self):
return self.email
第二次,如果仅首选默认打印机API,则将打印方法替换为:
@Slf4j
@Service
@RequiredArgsConstructor
public class PrinterDeviceServiceImpl implements PrinterDeviceService {
@Override
public StreamEx<PrintService> getAvailablePrinters() {
return of(PrintServiceLookup.lookupPrintServices(null, null));
}
@Override
public boolean isPrinterExists(String printerName) {
return getAvailablePrinters()
.anyMatch(p -> p.getName().equals(printerName));
}
@Override
public PrintService getPrinter(String printerName) {
return getAvailablePrinters()
.findFirst(p -> p.getName().equals(printerName))
.orElse(null);
}
@Override
public Mono<PrintTaskStatus> print(String printerName, InputStream source) {
try {
PrintService printer = getPrinter(printerName);
if (printer == null) {
return Mono.error(new RuntimeException("printer is null"));
}
PDDocument document = Unchecked.supplier(() -> PDDocument.load(source));
PrinterJob job = PrinterJob.getPrinterJob();
job.setPageable(new PDFPageable(document, Orientation.PORTRAIT));
job.setPrintService(printer);
Paper paper = new Paper();
paper.setSize(500, 500); //TODO: lets get it from configs or task request
paper.setImageableArea(0.0, 0.0, paper.getWidth(), paper.getHeight()); // no margins
// custom page format
PageFormat pageFormat = new PageFormat();
pageFormat.setPaper(paper);
Book book = new Book();
book.append(new PDFPrintable(document), pageFormat, document.getNumberOfPages());
job.setPageable(book);
HashPrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();
attr.add(OrientationRequested.PORTRAIT);
attr.add(PrintQuality.HIGH);
job.print(attr);
return Mono.create(sink -> {
/*If exec thread is UI or from http pool, then maybe better idea is to attach it to another independent one or run print in another one!*/
while (!isPrintCompleted(printer)) {
log.debug("I'm waiting to printer processed queue");
Unchecked.runnable(() -> Thread.sleep(1000));
}
/*you can wait some fixed or dynamic time based on how big your document etc and finish with error state if it needed*/
log.debug("printer queue have processed :)");
sink.success(PrintTaskStatus.Completed);
});
} catch (Throwable ex) {
ExceptionHelpers.logError(ex, log);
return Mono.just(PrintTaskStatus.Failed);
}
}
private boolean isPrintCompleted(PrintService printer) {
return Arrays.stream(printer.getAttributes().toArray())
.filter(att -> att instanceof QueuedJobCount)
.map(QueuedJobCount.class::cast)
.findFirst()
.map(queuedJobCount -> queuedJobCount.getValue() == 0)
.orElse(false);
}
}
祝你好运:)