我在用java打印PDF时遇到了一个问题。我知道Java不支持本机打印PDF,因为Java没有PDF渲染器。为了解决这个问题,我使用了一个PDFRenderer库,下面是一个使用它打印的示例:
File f = new File("myfile.pdf");
FileInputStream fis = new FileInputStream(f);
FileChannel fc = fis.getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0,
fc.size());
PDFFile pdfFile = new PDFFile(bb);
PDFPrintPage pages = new PDFPrintPage(pdfFile);
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
pjob.setJobName(f.getName());
pjob.setPrintService(mPrintService);
Book book = new Book();
book.append(pages, pf, pdfFile.getNumPages());
pjob.setPageable(book);
pjob.print();
它工作正常,但我需要一些方法来了解我的打印机工作状态。我需要知道我的打印机工作什么时候完成,我才能开始另一个。Java API对DocPrintJob和PrintJobListener有很好的解决方案,但我需要使用PrinterJob进行PDF打印。那么,我怎样才能像在DocPrintJob中一样从PrinterJob中监听作业状态呢?
对于2020年在这里处理这个问题的任何人来说,我发现了一种非常巧妙的打印PDF文件的方法,同时能够监控打印工作,而不使用JavaFX——因为人们似乎不太喜欢使用JavaFX打印PDF文件,我也不喜欢热衷于对象节点打印,因为在我看来,要把打印出来看起来像一个普通的文档真的很难...JavaFX似乎喜欢这样的想法——基本上——屏幕拍摄你的表单的一部分,然后将快照渲染成图形,然后你必须为打印机缩放它,结果它看起来有点奇怪...而像很好地拍摄这样的东西格式化的超文本标记语言,并通过PDF库打印它非常干净,非常快。这就是我的发现:
首先,我使用这个免费的库将我的超文本标记语言String渲染成PDF文件。以下是该库的Maven源代码:
<dependency>
<groupId>org.icepdf.os</groupId>
<artifactId>icepdf-core</artifactId>
<version>6.2.2</version>
</dependency>
这是我渲染PDF的代码:
String docPath = "/Users/michael/Documents/JavaFile.pdf";
String html = "<html>Any HTML Code you want, including embedded CSS for a really clean look</html>
OutputStream outputStream = new FileOutputStream(docPath);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(outputStream);
outputStream.close();
这是我用来打印PDF的课程。。。它有点长,但非常简单,并且使用了本机Java API,这很好(我使用的是1.8):
import javafx.application.Platform;
import javafx.scene.control.Label;
import java.io.*;
import javax.print.*;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;
public class PrintHandler {
private void delay(int msec) {
try {
Thread.sleep(msec);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public PrintHandler (FileInputStream fis, Label statusLabel) {
this.statusLabel = statusLabel;
this.fis = fis;
}
private FileInputStream fis;
private Label statusLabel;
private String state;
public void startPrintJob () {
try {
Platform.runLater(()->statusLabel.setText("PRINTING"));
delay(5000);
InputStream is = new BufferedInputStream(this.fis);
DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob printJob = service.createPrintJob();
JobMonitor monitor = new JobMonitor();
printJob.addPrintJobListener(monitor);
Doc doc = new SimpleDoc(is, flavor, null);
printJob.print(doc, null);
monitor.waitForJobCompletion();
is.close();
} catch (PrintException | IOException e) {
e.printStackTrace();
}
}
private class JobMonitor extends PrintJobAdapter {
private boolean notify = false;
final int DATA_TRANSFERRED = 10;
final int JOB_COMPLETE = 11;
final int JOB_FAILED = 12;
final int JOB_CANCELED = 13;
final int JOB_NO_MORE_EVENTS = 14;
final int JOB_NEEDS_ATTENTION = 15;
private int status;
@Override
public void printDataTransferCompleted(PrintJobEvent pje) {
status = DATA_TRANSFERRED;
markAction();
}
@Override
public void printJobCompleted(PrintJobEvent pje) {
status = JOB_COMPLETE;
markAction();
}
@Override
public void printJobFailed(PrintJobEvent pje) {
status = JOB_FAILED;
markAction();
}
@Override
public void printJobCanceled(PrintJobEvent pje) {
status = JOB_CANCELED;
markAction();
}
@Override
public void printJobNoMoreEvents(PrintJobEvent pje) {
status = JOB_NO_MORE_EVENTS;
markAction();
}
@Override
public void printJobRequiresAttention(PrintJobEvent pje) {
status = JOB_NEEDS_ATTENTION;
markAction();
}
private void markAction() {
synchronized (JobMonitor.this) {
notify = true;
JobMonitor.this.notify();
}
}
public synchronized void waitForJobCompletion() {
Runnable runner = ()->{
boolean keepRunning = true;
while (keepRunning) {
try {
while (!notify) {
wait();
}
html" target="_blank">switch(this.status){
case DATA_TRANSFERRED:
state = "DATA_TRANSFERRED";
break;
case JOB_COMPLETE:
state = "JOB_FINISHED";
keepRunning = false;
break;
case JOB_FAILED:
state = "JOB_FAILED";
keepRunning = false;
break;
case JOB_CANCELED:
state = "JOB_CANCELED";
keepRunning = false;
break;
case JOB_NO_MORE_EVENTS:
state = "JOB_COMPLETE";
keepRunning = false;
break;
case JOB_NEEDS_ATTENTION:
state = "JOB_NEEDS_ATTENTION";
break;
}
Platform.runLater(()->statusLabel.setText(state));
delay(5000);
notify = false;
}
catch (InterruptedException e) {}
}
delay(5000);
Platform.runLater(()->statusLabel.setText(""));
};
Thread monitor = new Thread(runner);
monitor.start();
}
}
}
下面是我如何调用类来打印和监视作业:
FileInputStream fis = new FileInputStream(docPath);
Label jobStatus = new Label(); //Already in my AnchorPane but included here for clarity
new PrintHandler(fis,jobStatus).startPrintJob();
javafx.print
Enum PrinterJob.JobStatus
java.lang.Object
java.lang.Enum<PrinterJob.JobStatus>
javafx.print.PrinterJob.JobStatus
public static PrinterJob.JobStatus[] values()
Returns an array containing the constants of this enum type, in the order they are declared. This method may be used to iterate over the constants as follows:
for (PrinterJob.JobStatus c : PrinterJob.JobStatus.values())
System.out.println(c);
我正在使用泽西开发一个API,并希望将其准备好部署到Google App Engine。但是,当我在Postman上测试时,GET函数有效,但POST函数无效。我只收到一条简短的错误消息,即“错误415不支持的媒体类型”,我无法确定哪里出了问题。 请求资源类 请求服务等级 网状物XML 提前感谢所有帮助我指出并解决问题并回答我问题的人。
问题内容: 我如何获得的?通过我的意思是得到它是否有一个复选标记与否。 问题答案: 创建它时,它需要一个关键字参数。从传递。选中或取消选中该框会将包含的值设置为相应的布尔状态。可以通过以下方式访问: 已检查=> 未检查=>
问题内容: 说我有一个 现在,我需要单击它的状态。我的意思是我需要知道是否单击了它。 问题答案: 您还可以使用itemListener的itemStateChanged方法,如下所示: 并且您想知道后者使用方法的状态
问题内容: 我正在尝试使用sun.misc.BASE64Encoder / Decoder,但是此代码: 返回“ test / string / XML /”,我很尴尬 问题答案: 不要使用或类。不保证在不同版本的jre之间它们是一致的。 使用commons编解码器 和
问题内容: 我正在将一些数据写入Excel文件,但是我不知道如何调整代码以便能够控制要写入的工作表: 而不是,我该怎么说(这是VBA语法的样子……)? 问题答案: 你应该用 PS:您应该检查工作表中是否包含工作表名称
我对java.sql.Statement的方法getGeneratedKeys()有问题 首先我的代码: 创造sql:(HSQLDB) 从DAO创建方法: 然后,我对生成的密钥进行了单元测试: 当我运行测试时,我得到一个失败和以下日志: 所以问题是