zoukankan      html  css  js  c++  java
  • 关于这两天研究Java打印pdf方法的记录

    这两天在研究Java调用打印机打印PDF文件的方法,学到了不少东西,特别来记录一下。

    关于Java打印网上最多的而且也是Java正统的打印方法就是使用PrintService,一套比較标准的打印代码例如以下:

    public class PrintDemo {
    
    	public static void main(String[] args) {
    		JFileChooser fileChooser = new JFileChooser(); // 创建打印作业
    		int state = fileChooser.showOpenDialog(null);
    		if (state == JFileChooser.APPROVE_OPTION) {
    			File file = fileChooser.getSelectedFile(); // 获取选择的文件
    			// 构建打印请求属性集
    			HashPrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
    			// 设置打印格式,由于未确定类型。所以选择autosense
    			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();
    					Doc doc = new SimpleDoc(fis, flavor, das);
    					job.print(doc, pras);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }

    可是经过尝试之后,发现pdf文件并没有以pdf的格式打印出来,而是打印出乱码(也就是文件的二进制码)

    初步猜想是打印机无法识别吧。于是将上面的DocFlavor改成DocFlavor.INPUT_STREAM.PDF;

    那么printService[]将会为null,为什么呢?由于lookupDefaultPrintService()方法仅仅会返回支持docFlavor的打印机~

    若未通过docFlavor来过滤打印机。而直接进行打印时。会报错:invalid flavor,也就是不支持该类型~

    事实上我们看docFlavor。它事实上也就是发送到打印机的数据流的content-type,类似到web中,也就是不支持该content-type。那么就比較easy理解了。

    后来从网上找到的解释是:

    Java print service API本身支持打印, 但其并不具有解释PDF文件的能力,也就是说,用标准的Java Print API可以打印PDF文件, 但所用的打印机必须支持PDF打印标准,即打印机支持Post Script标准, 而这样的打印机通常昂贵,眼下市场上流通的便宜打印机(使用基于主机的驱动程序)基本不支持


    那怎么办呢?难道我们就没办法通过Java程序来打印pdf文件了吗?无论有没有,至少要去试试吧~

    发现网上并没有特别好的解决方式。

    大概收集了几种:

    1、比較偷懒的方法,调外挂程序来实现打印,最典型的就是Adobe Reader

    2、使用PdfRenderer等第三方库先将pdf文件转换成图片,那么就能够调用PrintService来打印了


    先说第一种方法吧~

    首先你的电脑上得装上Adobe Reader,调用Adobe Reader来打印须要依赖acrord32这个命令

    我们知道在Java中要调用命令行须要Runtime对象,详细代码例如以下:

    public static boolean printPdf(String pdfPath){
    		try{
    			Runtime.getRuntime().exec("cmd.exe /C start acrord32 /P /h " + pdfPath);
    			return true;
    		}catch(Exception e){
    			e.printStackTrace();
    			return false;
    		}
    	}

    这里调用了Adobe Reader的acrord32.exe方法,以下来介绍下这个命令的參数。 

    acrord32.exe filename - 运行Adobe Reader,而且浏览PDF 

    其它还支持的參数有: 

    AcroRd32.exe /p filename - 运行Adobe Reader,而且打印一个PDF文件 

    AcroRd32.exe /t path printername drivername portname 

    初始化Adobe Reader, 不弹出打印对话框。然后结束打印 

    /t 命令所需的四个參数有 

    path - 打印文件路径 

    printername - 打印机名字 

    drivername - 打印机驱动名字 

    portname - 打印机端口 

    其它的參数: 

    /n 开一个新的Adobe Reader, 虽然有Adobe Reader已经打开 (静默打印不用) 

    /s 打开一个Adobe Reader不开splash screen 

    /o 打开一个Adobe Reader不开打开文件对话框 

    /h 以最小化方式打开一个Adobe Reader (静默打印使用)

  • 相关阅读:
    hdu 4476 Cut the rope (2-pointer && simulation)
    hdu 1286 找新朋友 (容斥原理 || 欧拉函数)
    函数存储的另一种思路
    grunt 入门 应用grunt对代码进行压缩
    sublime flatLand 主题
    如何应用r.js对requirejs下的js代码合并
    如何在requirejs下引用bootstrap
    学习在requirejs下如何使用underscore.js模板
    应用js函数柯里化currying 与ajax 局部刷新dom
    js 函数arguments一种用法
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5333205.html
Copyright © 2011-2022 走看看