当前位置: 首页 > 知识库问答 >
问题:

PDF PrinterJobs获取工作状态

白星渊
2023-03-14

我在用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中监听作业状态呢?

共有2个答案

商夜洛
2023-03-14

对于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();
乜业
2023-03-14
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创建方法: 然后,我对生成的密钥进行了单元测试: 当我运行测试时,我得到一个失败和以下日志: 所以问题是