功能描述:
在二手车项目中需要实现一个自动打印的功能。将打印的设置在java代码中写好,直接调用打印机打印,不需要有打印设置的页面。这里我使用的是Java自带的方式,一开始是打印pdf,但是由于公司的打印机不能识别application/pdf类型,因此最后我打印的是pdf转换的jpg图片。
(说明:最后我写的功能正常执行并打印出图片,但是由于该项目是SaaS软件,服务器由公司维护,而该代码执行的环境是需要运行程序的服务器与打印机在同一个局域网,这样才能正常识别,所以没有使用。为防止你走弯路,参考我的代码之前最好问清楚服务器是在哪儿维护)
代码如下:
1.获取输入流(这里是通过我们公司的pdf服务器的路径获得的)
@RequestMapping(value = "/printTransferPdf" ,method = RequestMethod.POST) @ApiOperation(value = "打印过户单据pdf", notes = "打印过户单据pdf" ,tags = {"web"}) public AbstractOutputDto downloadTransferPdf(@RequestBody PrintTransferOps ops )throws Exception{ PdfOutput output=transferService.createTransferPDF(ops); URL url=new URL(output.getPicPath()); URLConnection conn = url.openConnection(); InputStream is = conn.getInputStream(); System.out.println(output.getPicPath()); AbstractOutputDto abstractOutputDto= transferService.printPDF(is); return abstractOutputDto; }
2.打印功能
public AbstractOutputDto printPDF(InputStream in) throws IOException { AbstractOutputDto abstractOutputDto = new AbstractOutputDto(); //1.得到一个文件的输入流 BufferedInputStream fiStream = new BufferedInputStream(in); //这是要打印文件的格式,如果是PDF文档要设为自动识别 DocFlavor fileFormat = DocFlavor.INPUT_STREAM.JPEG; DocAttributeSet das=new HashDocAttributeSet(); das.add(OrientationRequested.PORTRAIT); //2.得到要打印的文档类DOC Doc myDoc = new SimpleDoc(fiStream, fileFormat, das); //3.生成一个打印属性设置对象 PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); /*aset.add(new Copies(1));//Copies-打印份数1份 aset.add(MediaSizeName.ISO_A4);//A4纸张 aset.add(Sides.ONE_SIDED);//双面打印*/ //4.关键一步,得到当前机器上所有已经安装的打印机 //传入的参数是文档格式跟打印属性,只有支持这个格式与属性的打印机才会被找到 PrintService printService=PrintServiceLookup.lookupDefaultPrintService(); if (printService!= null) { DocFlavor[] flavors=printService.getSupportedDocFlavors(); for (int i = 0; i < flavors.length; i++) { System.out.println("\t" + flavors[i]); } //5.用打印服务生成一个文档打印任务,这里用的是第一个服务 //也可以进行筛选,services[i].getName()可以得到打印机名称,可用名称进行比较得到自己想要的打印机 DocPrintJob job=printService.createPrintJob(); job.addPrintJobListener(new PrintJobListener() { @Override public void printJobRequiresAttention(PrintJobEvent arg0) { System.out.println("printJobRequiresAttention"); } @Override public void printJobNoMoreEvents(PrintJobEvent arg0) { System.out.println("通知客户端,不需要再提供事件"); } @Override public void printJobFailed(PrintJobEvent arg0) { System.out.println("通知客户端无法完成作业,必须重新提交"); } @Override public void printJobCompleted(PrintJobEvent arg0) { System.out.println("打印结束"); } @Override public void printJobCanceled(PrintJobEvent arg0) { System.out.println("作业已被用户或者程序取消"); } @Override public void printDataTransferCompleted(PrintJobEvent arg0) { System.out.println("数据已成功传输打印机"); } }); try { //6.最后一步,执行打印文档任务,传入的参数是Doc文档类,与属性 job.print(myDoc, aset);//成功后电脑会提示已有文档添加到打印队列 abstractOutputDto.setStatus(1); abstractOutputDto.setMsg("打印任务已添加"); } catch (PrintException pe) { pe.printStackTrace(); } } else { abstractOutputDto.setStatus(0); abstractOutputDto.setMsg("打印机未连接"); } return abstractOutputDto; }
注意:
我在写的时候遇到了几个问题:
1.PrintServiceLookup.lookupPrintServices()方法识别的打印机是需要符合它的文档格式和打印属性的。可能导致获取不到PrintService。最后我使用lookupDefaultPrintService方法获取的默认打印机,这需要本地设置一下。
2.打印文件的格式最好设具体值,设置为自动识别的话可能会出问题,导致传输的数据不被打印机处理
3.printService.getSupportedDocFlavors方法可以遍历出该打印机支持的文件格式
4.给文档打印任务添加监听可以帮助查看哪一步出现了问题。我传入pdf数据的时候就是打印机明明获取了却不处理,也不报错,闹心。
更多推荐
使用java自带的方式调用打印机打印图片
发布评论