关于java打印PDF的调用

研究自:http://blog.csdn.net/u012345283/article/details/41011977java

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

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

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;code

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

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

其实咱们看docFlavor,它其实也就是发送到打印机的数据流的content-type,相似到web中,也就是不支持该content-type,那么就比较容易理解了。图片

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

Java print service API自己支持打印, 但其并不具备解释PDF文件的能力,也就是说,用标准的Java Print API可以打印PDF文件, 但所用的打印机必须支持PDF打印标准,即打印机支持Post Script标准, 而这种打印机一般昂贵,目前市场上流通的廉价打印机(使用基于主机的驱动程序)基本不支持get

 

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

发现网上并无特别好的解决方案。大概收集了几种:

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

二、使用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 (静默打印使用)

相关文章
相关标签/搜索