Java 实现打印文件详解(附demo)

尘心
尘心
尘心
9
文章
0
评论
2020-08-1813:08:00 评论 2,121 5461字
摘要

前言:公司最新需要使用到Java 打印,且项目属于C/S结构。故本文讲述的并不是Java Web打印。 说起来也比较头疼,上网查资料,发现示例都不太完善,总会有这样那样的问题。故想把自己的心得写出来供大家分享,学习!

Java 实现打印文件详解

前言:公司最新需要使用到Java 打印,且项目属于C/S结构。故本文讲述的并不是Java Web打印。 说起来也比较头疼,上网查资料,发现示例都不太完善,总会有这样那样的问题。故想把自己的心得写出来供大家分享,学习!

提示:因本人项目原因,故着重实现pdf文件的打印,其他格式也会讲解!

实现打印的几种方式

  • 1.使用 Java原生自带打印功能打印
  • 2.使用 jacob 工具包打印
  • 3.使用 PDFBox 打印

Java 原生打印:

有一下几种实现方式:

实现打印对象:

  • 实现Printable接口
  • 使用工具箱自带的打印对象(Toolkit.getDefaultToolkit().getPrintJob)
  • 通过 javax.print.PrintSerivceLookup 查找定位打印对象

打印工作:

基本都是调用print();方法进行打印。

废话不多说,上代码

**实现Printable接口:**
// 此种方式必须实现 Printable接口private void printTextAction(String printStr){printStr = area.getText().trim(); // 打印字符串if (printStr != null && printStr.length() > 0){PAGES = getPagesCount(printStr);// 分页// 创建打印对象PrinterJob myPrtJob = PrinterJob.getPrinterJob();// 页面格式PageFormat pageFormat = myPrtJob.defaultPage();myPrtJob.setPrintable(this, pageFormat);if (myPrtJob.printDialog()) // 显示打印对话框{try{myPrtJob.print(); // 开始打印}catch(PrinterException pe){pe.printStackTrace();}}}else{JOptionPane.showConfirmDialog(null, "Sorry, Printer Job is Empty, Print Cancelled!", "Empty", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE);}}/* 分页 */public int getPagesCount(String curStr){int page = 0;int position, count = 0;String str = curStr;while(str.length() > 0)  // 文本尚未计算完毕{position = str.indexOf("
");count += 1;// 统计行数if (position != -1)str = str.substring(position + 1);  // 截取尚未计算的文本elsestr = "";}if (count > 0)page = count / 54 + 1; // 以总行数除以 54 获取总页数return page;// 返回需打印的总页数}

Java 原生方式2

// 打印字符private void printText2Action(String printStr){if (printStr != null && printStr.length() > 0){try{ PAGES = getPagesCount(printStr);DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;PrintService printService = PrintServiceLookup.lookupDefaultPrintService(); // 静默打印DocPrintJob job = printService.createPrintJob();PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();DocAttributeSet das = new HashDocAttributeSet();Doc doc = new SimpleDoc(this, flavor, das);job.print(doc, pras);}catch(PrintException pe){pe.printStackTrace();}}else{JOptionPane.showConfirmDialog(null, "Sorry, Printer Job is Empty, Print Cancelled!", "Empty", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE);}}

原生方式3:也是本文的一个重点

// 打印文件private void printFileAction(){// 创建一个文件选择器,构造函数存放的是当前用户路径JFileChooser fileChooser = new JFileChooser(SystemProperties.USER_DIR);// 显示文件选择对话框int state = fileChooser.showOpenDialog(this);// 选择完成if (state == fileChooser.APPROVE_OPTION){// 获取选择到的文件File file = fileChooser.getSelectedFile();// 打印属性,可为空PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();// 设置打印格式:自动DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;// 查询所有可打印服务PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras);// 定位默认打印服务PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();// 显示打印对话框PrintService service = ServiceUI.printDialog(null, 200, 200, printService, defaultService, flavor, pras);if (service != null){try{// 创建打印作业DocPrintJob job = service.createPrintJob();FileInputStream fis = new FileInputStream(file);DocAttributeSet das = new HashDocAttributeSet();pras.add(Chromaticity.MONOCHROME);// 请求横向模式//                    pras.add(OrientationRequested.LANDSCAPE);// Letter大小pras.add(MediaSizeName.NA_LETTER);// European A4 paperpras.add(MediaSizeName.ISO_A4);// 请求双面//                    pras.add(Sides.DUPLEX);Doc doc = new SimpleDoc(fis, flavor, das);job.print(doc, pras);}catch(Exception e){e.printStackTrace();}}}}

原生方式3:本来想用这种方式,结果发现其有一个非常严重的短板。就是txt,html,pdf等类型的文件,虽然其API提供了这些打印类型,但是发现,大部分打印机都不能正常打印,或者打印的内容为空白! 这可坑死老衲了,网上找原因,发现大家都反应这个问题,却没有解决。 因此笔者提供两种实现思路, 1.原生打印方式,图片,文字都是百分百能打印的。所以,可以将pdf转成图片,再进行打印。这无疑又绕了远路,但可以实现。 2. 采用其他方式实现打印。下文将继续介绍。

Java 打印文件之 jacob实现

优点:可以打印 excel,word 等复杂文档类型

缺点:电脑必须安装office,需要将库导入到指定位置。

所需环境:

库:jacob.dll

jar包:jacob.jar

jacob环境下载

private void doPrintDoc(List<File> fileList) { if (null == fileList || fileList.isEmpty()) {return;} // 初始化组件ComThread.InitSTA();  for (File file : fileList) { if (file == null || !file.exists()) {return;} int index = file.getName().indexOf(".");String extName = file.getName().toUpperCase().substring(index + 1); String comApp = "Word.Application";String property = "Documents"; if (extName.equals("DOC") || extName.equals("DOCX") || extName.equals("WPS")) {comApp = "Word.Application";property = "Documents";} else if (extName.equals("XLS") || extName.equals("XLSX") || extName.equals("ET")) {comApp = "Excel.Application";property = "Workbooks";} else if (extName.equals("PPT") || extName.equals("PPTX") || extName.equals("DPS")) {comApp = "PowerPoint.Application";property = "Presentations";} ActiveXComponent axc = new ActiveXComponent(comApp);try {if (!property.equals("Presentations")) {Dispatch.put(axc, "Visible", new Variant(false));}Dispatch document = axc.getProperty(property).toDispatch(); Dispatch doc = null; if (property.equals("Presentations")) {doc = Dispatch.call(document, "Open", file.getAbsolutePath(), true, true, false).toDispatch();} else {doc = Dispatch.invoke(document, "Open", Dispatch.Method, new Object[] { file.getAbsolutePath() }, new int[1]).toDispatch();}  Dispatch.call(doc, "PrintOut");Dispatch.call(doc, "Close");if (!property.equals("Presentations")) {axc.invoke("Quit", new Variant[] {});} } catch (Exception e) {e.printStackTrace();} finally {comApp = "";property = ""; }} ComThread.Release();}

这种方式,缺点太明显,不予采纳

最后一种 PDFBox实现

所需资源:pdfbox.jar/fontbox.jar 依赖包:commons-logging.jar

下载pdfbox(完整版),含源码和commons-logging.jar

private static void print() {try {File file = new File("C:/Users/Jason/Desktop/打印测试.pdf");PDDocument document = PDDocument.load(file);// 加载成打印文件PDFPrintable printable = new PDFPrintable(document);PrinterJob job = PrinterJob.getPrinterJob();job.setPrintable(printable);job.print();} catch (InvalidPasswordException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (PrinterException e) {e.printStackTrace();}}

这种方式简直太爽了,代码简洁,功能强大!推荐大家使用这个。不需要引用动态库 ,只需加入jar包即可!

End.

爱数据网专栏:大数据程序员笔记

作者简介:分享在开发中遇到的问题和使用的知识技术,总结多年开发经验。

个人CSDN主页: JavaBuilt 个人主页

  • 我的微信公众号
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: