自动打印在Java中不起作用

我需要以两种不同的方式打印pdf文件 – 通过网页,用户将看到打印预览并选择打印机并进行打印。 第二种方法是自动化打印,只需单击一个按钮,pdf就应该发送到打印机。

第一种打印方式是通过网页工作正常,但不是第二种方式。 成功检索默认打印机以进行自动打印,但未打印,我也没有收到任何错误。 以下是我的分析:

  1. 最初,我认为DocFlavor不受支持。 然后我列出了该打印机支持的DocFlavor ,其中一个是application / octet-stream,即DocFlavor.INPUT_STREAM.AUTOSENSE 。 所以打印机支持这种味道。
  2. 然后,我添加了PrintJobListener以检查打印作业是否失败。 当我将该监听器添加到printJob时,它会打印No_More_EventsDATA_TRANSFER_COMPLETE ,如果作业成功,则应该打印JOB_COMPLETE
  3. 最后一步是调试Java代码。 当我执行job.print() ,它进入Win32PrintJob.print()方法。 我做F6执行每一行,看看它在做什么。 我将它与GrepCode中的代码进行了比较 ,因为源代码未在eclipse中加载。 一切顺利,我看不出任何错误。 它没有进入的唯一地方是这个块,它检查mDestination值,因为我没有提供它,它没有通过。

请参阅以下代码:

 if (mDestination != null) { // if destination attribute is set try { FileOutputStream fos = new FileOutputStream(mDestination); byte [] buffer = new byte[1024]; int cread; while ((cread = instream.read(buffer, 0, buffer.length)) >= 0) { fos.write(buffer, 0, cread); } fos.flush(); fos.close(); } catch (FileNotFoundException fnfe) { notifyEvent(PrintJobEvent.JOB_FAILED); throw new PrintException(fnfe.toString()); } catch (IOException ioe) { notifyEvent(PrintJobEvent.JOB_FAILED); throw new PrintException(ioe.toString()); } notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE); notifyEvent(PrintJobEvent.JOB_COMPLETE); service.wakeNotifier(); return; } 

这是唯一一个说JOB_COMPLETE的地方。 我认为这个块是写入一个文件,这对我来说是不需要的。

我认为实际打印在Win32PrintJob.print()的相同方法中发生在以下行中。

 private native boolean More ...printRawData(byte[] data, int count); 

但这个是本机方法,因此我不知道其中发生了什么。

请让我知道为什么我无法打印PDF。

编辑:

附上代码来打印文件:

 PrintService pss = PrintServiceLookup.lookupDefaultPrintService(); DocPrintJob job = pss.createPrintJob(); DocAttributeSet das = new HashDocAttributeSet(); Doc document; try { document = new SimpleDoc(new FileInputStream(new File(fileName)), DocFlavor.INPUT_STREAM.AUTOSENSE, das); PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet(); job.addPrintJobListener(new PrintJobWatcher()); job.print(document, pras); } 

注意:我尝试过不同的风格,如PDF,PCL。 没有什么工作,我得到运行时错误,它不受支持。

您是否尝试过JPadel来打印PDF文件:

摘自示例代码

 final PdfBook pdfBook = new PdfBook(pdfDecoder, printJob.getPrintService(), attributes); pdfBook.setChooseSourceByPdfPageSize(false); final SimpleDoc doc = new SimpleDoc(pdfBook, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null); // used to track print activity printJob.addPrintJobListener(new PDFPrintJobListener()); try { printJob.print(doc, attributes); } catch (final Exception e) { LogWriter.writeLog("Exception " + e + " printing"); //  } 

除此之外,您还可以提供打印机名称并添加列表器PDFPrintJobListener

我最近有同样的任务,答案不是那么直接的第二个打印选项(也试过JPedal,Samba和其他解决方案……)。 最简单的打印方式(我最终尝试过)只是将文件放在打印机队列中,即根位置。 例如:MY_SERVER \ PRINTER_NAME \

问题现在变成了环境/操作系统,而不是Java环境。 通过安装在Windows计算机上的应用程序,您可以访问该文件夹,复制要打印的文件,然后瞧。 此外,使用您使用的方法,您还可以为打印作业指定名称,份数等。

但是,一旦应用程序安装在服务器上,它就是一个完全不同的球类游戏,特别是如果您正在使用Linux服务器。

首先,您必须将Windows地址转换为Linux地址,甚至尝试复制文件/打印它。

其次,这是关键,如果打印机不是更复杂/专有的数据流的一部分,那么打印机只是“接受文件”进行打印是非常罕见/困难的。 例如,当您执行“Ctrl + P”时,您可以找到与服务器甚至机器的打印机“通信语言”..这将主要是.xml文件或其他一些格式。

但是,为了“找出”这种格式,你必须开发(最终在Java中)一个可以调用该打印机的applet。

当然,您也可以尝试在该服务器上安装Cups4j或安装打印机服务器(假设您的工作位置不合适),但这会在打印机更改,添加到网络等时出现问题。

最后你要坚持使用“Ctrl + P”方法,制作一个在浏览器中调用“CTRL + P”的小型JS脚本,或者开始重新创建轮子,这不是一件坏事(因为有人选择这种方法也..但我没有在任何地方找到一个例子),但是你可能会花费更多的时间。

希望我能以某种方式提供帮助(对不起这篇文章很遗憾……但这是我搜索过的一个主题并且工作了很长一段时间)。