先用office2003或者2007编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc。经测试这样方式生成的word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。
客户要求用程序生成标准的word文档,要能打印,而且不能变形,以前用过很多解决方案,都在客户严格要求下牺牲的无比惨烈。
POI读word文档还行,写文档实在不敢恭维,复杂的样式很难控制不提,想象一下一个20多页,嵌套很多表格和图像的word文档靠POI来写代码输出,对程序员来说比去山西挖煤还惨,况且文档格式还经常变化。
iText操作Excel还行。对于复杂的大量的word也是噩梦。
直接通过JSP输出样式基本不达标,而且要打印出来就更是惨不忍睹。
Word从2003开始支持XML格式,用XML还做就很简单了。
大致的思路是先用office2003或者2007编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc。经测试这样方式生成的word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。
看看实际效果
首先用office【版本要2003以上,以下的不支持xml格式】编辑文档的样式,图中红线的部分就是我要输出的部分:
将编辑好的文档另存为XML
再用Firstobject free XML editor将xml中我们需要填数据的地方打上FreeMarker标记
最后生成的文档样式
主要程序代码:
1. package
2. import
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11. import
12. import
13. import
14. import
15. import
16. public class
17. private Configuration configuration = null;
18. public
19. new
20. "utf-8");
21. }
22. public void
23. //要填入模本的数据文件
24. new
25. getData(dataMap);
26. //设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,
27. //这里我们的模板是放在com.havenliu.document.template包下面
28. this.getClass(), "/com/havenliu/document/template");
29. null;
30. try
31. //test.ftl为要装载的模板
32. "test.ftl");
33. catch
34. e.printStackTrace();
35. }
36. //输出文档路径及名称
37. new File("D:/temp/outFile.doc");
38. null;
39. try
40. new BufferedWriter(new OutputStreamWriter(new
41. catch
42. e1.printStackTrace();
43. }
44. try
45. t.process(dataMap, out);
46. catch
47. e.printStackTrace();
48. catch
49. e.printStackTrace();
50. }
51. }
52. /**
53. * 注意dataMap里存放的数据Key值要与模板中的参数相对应
54. * @param dataMap
55. */
56. private void
57. {
58. "author", "张三");
59. "remark", "这是测试备注信息");
60. List
61. new
62. new
63. "2010-10-1");
64. "制定10月开发计划内容。");
65. _table1.add(t1);
66. new
67. "2010-10-2");
68. "开会讨论开发计划");
69. _table1.add(t2);
70. "table1", _table1);
71. List
72. new
73. for(int i=0;i<5;i++)
74. {
75. new
76. "测试开发计划"+i);
77. "张三——"+i);
78. "2010-10-1");
79. "2010-10-31");
80. "备注信息");
81. _table2.add(_t2);
82. }
83. "table2", _table2);
84. }
85. }