java操作word并通过打印机打印

1.本文使用工具类为Jacob 来操作word文档,  优点是功能强大, 直接操作word, 方便控制样式,缺点是配置复杂,只能用在windows平台,需要电脑上有wps或office

2.首先下载Jacob压缩包,将其中的 jacob-1.17-M2-x64.dll 文件放在 %JAVA_HOME%/jre/bin目录下 ,win7放在System32 目录下。(如果win7是32位系统,则放在 System64目录下,有点诡异)

3.在项目的resource目录下新建lib文件夹,将Jacob.jar 放在lib目录下

4.引入pom依赖

<dependency>
    <groupId>com.jacob</groupId>
    <artifactId>jacob</artifactId>
    <version>1.17</version>
    <scope>system</scope>
    <systemPath>${basedir}/src/main/resources/lib/jacob.jar</systemPath>
</dependency>

5.打开要操作的word,其中要填充的数据位使用占位符填充,格式为 {{变量名}},此处变量名需要与java中相应的变量名一致

6.在数据库中取出想要的数据,创建一个相对应的map

 

/**
     * 生成收据
     */
    @GetMapping("/contract")
    public AjaxResult Contract() {
        String fileName = DateUtils.timechuo() + ".docx";  //根据模板生成的文件名

        String templateFilePath = null;  
        String printerName = null;  //打印机的名字,也可以不指定


        //从数据库中查询订单信息
        /通过你自己的service在数据库中查询想要的数据
        
        for (Object o : jsonArray) {  //如果是多条数据  使用循环遍历  根据业务进行修改
            JSONObject ob = (JSONObject) o;

            String houseid = ob.getString("houseid");  
            String amount = ob.getString("shouldamount");
            String outtradeno = ob.getString("outtradeno");
           

            String houseNo = getHouseNo(houseid);

            //创建一个map 将数据库中的数据写进去
            Map<String,String> map = new HashMap<>();
            //map的键必须与word中的占位符一致, 如word中{{houseid}}则map键名为 "houseid"
            map.put("houseid",houseid);  
            map.put("Amount",amountUp);
            map.put("outtradeno",outtradeno);
 

            String path1 =  "D:/模板.docx";  //模板word路径
            String outFilePath = "D:/" + fileName;  //生成的word文件输出路径
            templateFilePath = path1;  //模板word路径


            //调用接口生成收据
            try {
                  //可以指定打印机
//                insertAndOutFile2(templateFilePath,outFilePath,map,printerName);
                //不指定打印机会选择默认打印机)
                insertAndOutFile2(templateFilePath,outFilePath,map);
                //修改打印状态
                ob.put("status",1);
                //这里调用你自己的service修改状态就可以了
                
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
        }


        return AjaxResult.success();

    }

    /**
     * 生成一个新的收据
     * @param templateFilePath word模板文件路径
     * @param outFilePath 填充后输出文件路径
     * @param map  key:word中的占位标签,value对应标签要替换的值。
     * @throws IOException
     */
    public void insertAndOutFile2(String templateFilePath, String outFilePath, Map<String,String> map, String printerName) throws Exception {
//        Map<String,Object> data = new HashMap<String, Object>();
//        data.put("title", "Poi-tl 模板引擎");//添加数据,键是 模板中的{{title}},值在渲染的时候会替换掉对应的标签

        XWPFTemplate template = XWPFTemplate.compile(templateFilePath).render(map); //编译模板,把数据塞入模板中,找到对应标签替换
        FileOutputStream out = new FileOutputStream(outFilePath);//新建导出文件
        template.write(out); //输出到流
        out.flush();
        out.close();
        template.close();
        PrintWordUtiil.printWord(outFilePath,printerName);

    }

    //重载 不需要传打印机名字的方法
    public void insertAndOutFile2(String templateFilePath, String outFilePath, Map<String,String> map) throws Exception {
//        Map<String,Object> data = new HashMap<String, Object>();
//        data.put("title", "Poi-tl 模板引擎");//添加数据,键是 模板中的{{title}},值在渲染的时候会替换掉对应的标签

        XWPFTemplate template = XWPFTemplate.compile(templateFilePath).render(map); //编译模板,把数据塞入模板中,找到对应标签替换
        FileOutputStream out = new FileOutputStream(outFilePath);//新建导出文件
        template.write(out); //输出到流
        out.flush();
        out.close();
        template.close();
        PrintWordUtiil.printWord(outFilePath);

    }

    //下边两个方法是生成文件夹和命名的  可用可不用

        /**
         * 以当前日期为名,创建新文件夹
         *
         * @return
         */
        private static String createNewDir() {
            SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
            return fmt.format(new Date());
        }

    /**
     * 为文件重新命名,命名规则为当前系统时间毫秒数
     *
     * @return string
     */
    private static String getFileNameNew() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return fmt.format(new Date());
    }

    

7.打印工具类,核心,需要打印的文件只需要调用 PrintWordUtil.printWord()方法,传入相应参数就可以了

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.Sides;
import java.awt.print.*;
import java.io.File;
import java.io.IOException;

public class PrintWordUtiil {

    //这个方法是需要传打印机名字的(即指定打印机) 下边有个重载的方法不需要传打印机名字
    public static void printWord(String filePath,String printerName) throws PrinterException {

//        初始化线程

        ComThread.InitSTA();
        ActiveXComponent word = new ActiveXComponent("Word.Application");
        //设置打印机名称
        if (printerName == null && printerName == ""){
            //如果打印机的名字为空,则默认机器首个打印机
            //  创建一个PrinterJob对象
            PrinterJob printerJob  =  PrinterJob.getPrinterJob();

            //  设置打印机
            PrintService printService  =  PrintServiceLookup.lookupDefaultPrintService();
            printerJob.setPrintService(printService);
            printerName = printService.getName();
            System.out.println("发现的打印机名名称为:"+printerName);
        }

        word.setProperty("ActivePrinter", new Variant(printerName));

        // 这里Visible是控制文档打开后是可见还是不可见,若是静默打印,那么第三个参数就设为false就好了
        Dispatch.put(word, "Visible", new Variant(false));
        // 获取文档属性
        Dispatch document = word.getProperty("Documents").toDispatch();
        // 打开激活文挡
        Dispatch doc=Dispatch.call(document, "Open", filePath).toDispatch();
        //Dispatch doc = Dispatch.invoke(document, "Open", Dispatch.Method,
        //  new Object[] { filePath }, new int[1]).toDispatch();
        try{
            Dispatch.callN(doc, "PrintOut");
            System.out.println("打印成功!");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("打印失败");
        }finally {
            try {
                if (doc != null) {
                    Dispatch.call(doc, "Close", new Variant(0));//word文档关闭
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            //退出
            word.invoke("Quit", new Variant[0]);

            //释放资源
            ComThread.Release();
            ComThread.quitMainSTA();
        }
    }


    public static void printWord(String filePath) throws PrinterException {

//        初始化线程

        ComThread.InitSTA();
        ActiveXComponent word = new ActiveXComponent("Word.Application");
        //设置打印机名称

        PrinterJob printerJob  =  PrinterJob.getPrinterJob();

        //  设置打印机
        PrintService printService  =  PrintServiceLookup.lookupDefaultPrintService();
        printerJob.setPrintService(printService);
        String printerName = printService.getName();
        System.out.println("发现的打印机名名称为:"+printerName);
        printWord(filePath,printerName);

    }
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值