Java打印文件

一、简介

在我们的实际工作中,经常需要实现打印功能。但由于历史原因,Java 提供的打印功能一直都比较弱。实际上最初的 jdk 根本不支持打印,直到 jdk1.1 才引入了很轻量的打印支持。实际上,SUN 公司也一直致力于 Java 打印功能的完善,而 Java2 平台则终于有了一个健壮的打印模式的开端, jdk1.4 则提供了一套完整的"Java 打印服务 API" (Java Print Service API),它对已有的打印功能是积极的补充。

这里打印对象主要是图片和pdf文件两种常见形式,其他office文件可以通过相应程序转成pdf进行打印,比如aspose(收费,需要破解)/openoffice(需要先搭建本地服务)/Jacob(只有windows)

二、打印实践

首先要保证电脑GUI打印能正常运行,否则连打印机都没有连接,那怎么打印?

1、JPG图片打印

打印JPG图片格式的文件,本次采用的Java原生的打印方式。jdk1.4之后对打印功能有了很好的支持。Java 的打印 API 主要存在于 java.awt.print 包中。而 jdk1.4 新增的类则主要存在于 javax.print 包及其相应的子包 javax.print.event javax.print.attribute 中。其中** javax.print 包中主要包含打印服务的相关类,而 javax.print.event 则包含打印事件的相关定义,javax.print.attribute 则包括打印服务的可用属性列表等**。可以很好的解决打印JPG图片格式的需求。

  • 优点:jdk的原生支持的打印功能,可直接使用,支持设置各项打印参数。

  • 缺点:局限性较大,只能打印一些图片和文本格式的文件。

public class PrintUtil {
    /**
     * 打印图片
     * @param file
     * @param printerName
     * @throws PrintException
     */
    public static void JPGPrint(File file,String printerName) throws PrintException {
        if (file == null||printerName==null) {
            System.err.println("缺少打印文件或者缺少打印机参数");
        }
        InputStream fis = null;
    
        try {
            // 设置打印格式,如果未确定类型,可选择autosense
            // 设置为jpg格式
            DocFlavor flavor = DocFlavor.INPUT_STREAM.JPEG;
            // 设置打印参数
            PrintRequestAttributeSet hashset = new HashPrintRequestAttributeSet();
            //份数
            hashset.add(new Copies(1));
            //装订
            //hashset.add(Finishings.STAPLE);
            //单双面
            hashset.add(Sides.DUPLEX);
            // 颜色
            hashset.add(Chromaticity.COLOR);
    
    
            // 定位打印服务
            PrintService printService = null;
            if (printerName != null) {
                //获得本台电脑连接的所有打印机
                PrintService[] printServices = PrinterJob.lookupPrintServices();
                if(printServices == null || printServices.length == 0) {
                    System.out.print("打印失败,未找到可用打印机,请检查。");
                    return ;
                }
                //匹配指定打印机
                for (int i = 0;i < printServices.length; i++) {
                    if (printServices[i].getName().contains(printerName)) {
                        printService = printServices[i];
                        break;
                    }
                }
                if(printService==null){
                    System.out.print("打印失败,未找到名称为" + printerName + "的打印机,请检查。");
                    return ;
                }
            }
    
            // 构造待打印的文件流
            fis = new FileInputStream(file);
            Doc doc = new SimpleDoc(fis, flavor, null);
            // 创建打印作业
            DocPrintJob job = printService.createPrintJob();
            job.print(doc, hashset);
        } catch (FileNotFoundException e1) {
            System.err.println("文件未找到");
            e1.printStackTrace();
        } finally {
            // 关闭打印的文件流
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    
    
    public static void main(String[] args) throws Exception {
        JPGPrint(new File("D:\\share\\111.jpg"),"MI");
    }
}

2、图片/pdf原生打印

这里pdf打印可能和硬件有关系,需要安装Adobe Reader,而且现在pdf也不使用此方法打印,可以用作借鉴

public class PrintUtil {

    /**
     * 打印服务
     * @param file 文件
     * @Param printerName 打印机名字
     * @param num 打印份数
     */
    public static void paperPrint(File file, String printerName, int num){

        // 构建打印请求属性集
        DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
        // 设置打印格式
        PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
        // 查找所有的打印服务
        PrintService[] printServices = PrintServiceLookup.lookupPrintServices(flavor, pras);

        // 打印服务
        PrintService printService = null;
        for (PrintService ps : printServices) {
            String psName = ps.toString();
            // 选用指定打印机,需要精确查询打印机就用equals,模糊查询用contains,这里使用了模糊查找
            if (psName.contains(printerName)) {
                printService=ps;
                break;
            }
        }
        // 如果找不到打印机
        if(printService == null){
            System.err.println("找不到打印机");
            return;
        }
        // 文件不存在
        if (!file.exists() || !file.isFile()) {
            System.err.println("文件不存在");
            return;
        }
        String fileName = file.getName();
        // 获取图片后缀名,设置打印文件格式
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        switch (suffix) {
            case "jpg":
            case "jpeg":
                flavor = DocFlavor.INPUT_STREAM.JPEG;
                break;
            case "png":
                flavor = DocFlavor.INPUT_STREAM.PNG;
                break;
            case "pdf":
                flavor = DocFlavor.INPUT_STREAM.PDF;
                break;
            case "gif":
                flavor = DocFlavor.INPUT_STREAM.GIF;
                break;
            default:
                System.err.println("其他类别文件不支持打印");
                return;
        }
        // 设置打印文件名
        pras.add(new JobName(fileName, Locale.CHINA));
        // 设置打印方向
        pras.add(OrientationRequested.LANDSCAPE);
        // 设置打印区域
        //MediaPrintableArea mp = new MediaPrintableArea(0, 100, 230, 203, Size2DSyntax.MM);
        //pras.add(mp);
        // 设置彩打或者黑白打印
        pras.add(Chromaticity.MONOCHROME);
        try {
            FileInputStream fis = new FileInputStream(file);
            HashDocAttributeSet das = new HashDocAttributeSet();

            for (long i = 0; i < num; i++) {
                // 使用打印服务生成打印任务
                DocPrintJob job = printService.createPrintJob();
                // 获取需要打印的文档类doc
                SimpleDoc doc = new SimpleDoc(fis, flavor, das);
                // 监听打印任务
                job.addPrintJobListener(new PrintJobListener() {
                    @Override
                    public void printDataTransferCompleted(PrintJobEvent pje) {
                        System.out.println("成功发送任务:" + fileName);
                    }

                    @Override
                    public void printJobCompleted(PrintJobEvent pje) {
                        System.out.println("打印任务完成!");
                    }

                    @Override
                    public void printJobFailed(PrintJobEvent pje) {
                        System.out.println("打印任务失败:" + fileName);
                    }

                    @Override
                    public void printJobCanceled(PrintJobEvent pje) {
                        System.out.println("取消打印任务!");
                    }

                    @Override
                    public void printJobNoMoreEvents(PrintJobEvent pje) {
                        System.out.println("没有更多方法提供打印机调用!");
                    }

                    @Override
                    public void printJobRequiresAttention(PrintJobEvent pje) {
                        System.out.println("纸张已用完");
                    }
                });
                job.print(doc, pras);
            }
        } catch (PrintException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        paperPrint(new File("D:\\share\\111.png"),"MI",1);
        //paperPrint(new File("D:\\share\\123.pdf"),"MI",1);
    }


}

3、PDF文件格式打印实现

这里使用Apache PDFbox来实现进行PDF文件格式的打印。Apache PDFbox是一个开源的、基于Java的、支持PDF文档生成的工具库,它可以用于创建新的PDF文档,修改现有的PDF文档,还可以从PDF文档中提取所需的内容。Apache PDFBox还包含了数个命令行工具。在此,我们只研究打印功能。

  • 优点:功能强大,开源软件,较完美的解决了PDF格式文件的一系列处理,使用方便

首先导入依赖

<dependency>
  <groupId>org.apache.pdfbox</groupId>
  <artifactId>pdfbox</artifactId>
  <version>2.0.6</version>
</dependency>

具体代码实现

public class PrintUtil {

    public static PrinterJob getPrintServiceByName(String printerName) throws Exception{
        PrinterJob job = PrinterJob.getPrinterJob();
        // 遍历查询打印机名称
        boolean flag = false;
        for (PrintService ps : PrinterJob.lookupPrintServices()) {
            String psName = ps.toString();
            // 选用指定打印机,需要精确查询打印机就用equals,模糊查询用contains,这里使用了模糊查找
            if (psName.contains(printerName)) {
                flag = true;
                job.setPrintService(ps);
                break;
            }
        }
        if(!flag){
            System.err.println("未找到打印机");
            throw new RuntimeException("打印失败,未找到名称为" + printerName + "的打印机,请检查你的打印机名字");
        }
        return job;
    }


    /**
     * 获取打印纸的大小范围
     * @return
     */
    public static Paper getPaper() {
        Paper paper = new Paper();
        // 默认为A4纸张,对应像素宽和高分别为 595, 842
        int width = 595;
        int height = 842;
        // 设置边距,单位是像素,10mm边距,对应 28px
        int marginLeft = 10;
        int marginRight = 0;
        int marginTop = 10;
        int marginBottom = 0;
        paper.setSize(width, height);
        // 下面一行代码,解决了打印内容为空的问题
        paper.setImageableArea(marginLeft, marginRight, width - (marginLeft + marginRight), height - (marginTop + marginBottom));
        return paper;
    }

    /**
     * 设置打印属性
     * @param
     */
    public static void paperPDFPrint(PDDocument document, PrinterJob job)  {
        try {
            // 设置纸张及缩放
            PDFPrintable pdfPrintable = new PDFPrintable(document, Scaling.ACTUAL_SIZE);
            // 设置多页打印
            Book book = new Book();
            // 设置打印格式
            PageFormat pageFormat = new PageFormat();
            //设置纸张
            pageFormat.setPaper(getPaper());
            // 设置打印纸的方向,这是纵向
            pageFormat.setOrientation(PageFormat.PORTRAIT);
            // 设置一些属性 是否缩放 打印张数等
            book.append(pdfPrintable, pageFormat, document.getNumberOfPages());
            job.setPageable(book);
            // 设置打印份数
            job.setCopies(1);
            //添加打印属性
            HashPrintRequestAttributeSet pars = new HashPrintRequestAttributeSet();
            // 设置单双页
            pars.add(Sides.ONE_SIDED);
            // 设置彩打或者黑白打印
            pars.add(Chromaticity.MONOCHROME);
            // 打印质量
            pars.add(PrintQuality.NORMAL);
            // 这是直接打印
            job.print(pars);

        } catch (PrinterException e) {
            System.err.println("未正常连接打印机");
            e.printStackTrace();
        } catch (Exception e){
            System.err.println("打印机打印异常");
            e.printStackTrace();
        }
    }

    /**
     * 打印pdf文件
     * @param pdfPath
     * @param printerName
     * @return
     * @throws Exception
     */
    public static PDDocument printPdf(String pdfPath, String printerName) throws Exception {
        File file = new File(pdfPath);
        PDDocument document = PDDocument.load(file);
        PrinterJob job = getPrintServiceByName(printerName);
        paperPDFPrint(document, job);
        return document;
    }


    public static void main(String[] args) throws Exception {
          printPdf("D:\\share\\123.pdf","MI");
    }

}

参考文章:

https://blog.csdn.net/vatxiongxiaohui/article/details/83985896

https://blog.csdn.net/weixin_45944086/article/details/108148264

https://blog.csdn.net/weixin_46031754/article/details/121670267

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值