用户要求用程序生成标准的word文档,要能打印(有多个打印机时可以指定打印机进行打印,支持横向打印),而且不能变形,以前用过很多解决方案,都在客户严格要求下牺牲的无比惨烈。

   POI读word文档还行,写文档实在不敢恭维,复杂的样式很难控制不提,想象一下一个20多页,嵌套很多表格和图像的word文档靠POI来写代码输出,对程序员来说比去山西挖煤还惨,况且文档格式还经常变化。

   iText操作Excel还行,对于复杂的大量的word也是噩梦。

   Word从2003开始支持XML格式,用XML还做就很简单了。 大致的思路是先用office2003或者2007编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc。经测试这样方式生成的word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。

   具体代码请参见:https://www.cnblogs.com/zwqh/p/7182953.html ,此处不再赘述。

   另外还有一个比较好的生成各种美观的word的组件,分享一下:https://github.com/Sayi/poi-tl 。

   本文的重点是如何使用Java来打印word文档。

一、背景

    ·查找了Java打印的相关资料,总结如下:

  • Java自带的PrintJob,提供的打印机制并不完整,只能打印pdf、txt、图片之类,无法打印html、word、excel等复杂文档。
  • 使用jacob组件打印word,详见:https://www.cnblogs.com/Joanna-Yan/p/5346084.html ,证实可用。但是不能指定打印机打印和不支持设定横向打印(可能是我没找到具体方法)。

    由于上述两种方法均无法满足客户需求,我只好亲自上阵,完美实现了客户需求,并在实施过程中运行良好。

二、我的解决方案

   使用printword.exe ,下载链接:https://download.csdn.net/download/dong707/10485755

   调用printword.exe 时,有3个参数:

-   path:word文档的路径(如果路径中有空格时,整个路径需要用双引号包起来),必填
- ip:打印机的IP(实际上该参数应为打印机的名字,但是我这边打印机的命名都是用ip来命名的,故用ip),实现指定打印机来打印,必填
- orientation:0 纵向打印,1 横向打印。可不填,默认纵向打印。

   使用方法:

   在命令行中输入:

   c:/printer/printword.exe path="d:/app data/test.doc" ip=192.168.0.101 orientation=1

   该命令行就是使用c:/printer/printword.exe调用ip为192.168.0.101的打印机(前提是要把这个ip的打印机添加到设备中,并且重命名为192.168.0.101,如下图所示),横向打印d:/app data/test.doc这个文档。

   既然通过命令行可以打印word了,那现在就可以通过java来执行命令行打印word了。

/* 获取cmd命令 */
try {
String cmd="cmd /c c:/printer/printword.exe ip=192.168.0.101 orientation=1 path=" + filePath;
System.out.println(cmd);
Process pro = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
String msg = null;
while ((msg = br.readLine()) != null) {
System.out.println(msg);
}
} catch (IOException exception) {

}
LOG.warn("打印完成");

   综上,算是使用了一个较为简便的方法实现了通过java调用指定打印机横向打印word,特分享至此,欢迎共同讨论。