Java完美生成word的解决方案

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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【Firstobject free XML editor的使用见这里】将xml中我们需要填数据的地方打上FreeMarker标记【FreeMarker的语法见这里】
最后生成的文档样式
主要程序代码:
view sourceprint?01 package com.havenliu.document;
02
03 import java.io.BufferedWriter;
04 import java.io.File;
05 import java.io.FileNotFoundException;
06 import java.io.FileOutputStream;
07 import java.io.IOException;
08 import java.io.OutputStreamWriter;
09 import java.io.Writer;
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14
15 import freemarker.template.Configuration;
16 import freemarker.template.Template;
17 import freemarker.template.TemplateException;
18
19 public class DocumentHandler {
20 private Configuration configuration = null;
21
22 public DocumentHandler() {
23 configuration = new Configuration();
24 configuration.setDefaultEncoding("utf-8");
25 }
26
27 public void createDoc() {
28 //要填入模本的数据文件
29 Map dataMap=new HashMap();
30 getData(dataMap);
31 //设置模本装置方法和路径,FreeMarker支持多种模板装载方法。

可以重servlet,classpath,数据库装载,
32 //这里我们的模板是放在com.havenliu.document.template包下面
33 configuration.setClassForTemplateLoading(this.getClass(),
"/com/havenliu/document/template");
34 Template t=null;
35 try {
36 //test.ftl为要装载的模板
37 t = configuration.getTemplate("test.ftl");
38 } catch (IOException e) {
39 e.printStackTrace();
40 }
41 //输出文档路径及名称
42 File outFile = new File("D:/temp/outFile.doc");
43 Writer out = null;
44 try {
45 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
46 } catch (FileNotFoundException e1) {
47 e1.printStackTrace();
48 }
49
50 try {
51 t.process(dataMap, out);
52 } catch (TemplateException e) {
53 e.printStackTrace();
54 } catch (IOException e) {
55 e.printStackTrace();
56 }
57 }
58
59 /**
60 * 注意dataMap里存放的数据Key值要与模板中的参数相对应
61 * @param dataMap
62 */
63 private void getData(Map dataMap)
64 {
65 dataMap.put("author", "张三");
66 dataMap.put("remark", "这是测试备注信息");
67 List
68 _table1=new ArrayList
69 ();
70
71 Table1 t1=new Table1();
72 t1.setDate("2010-10-1");
73 t1.setText("制定10月开发计划内容。

");
74 _table1.add(t1);
75
76 Table1 t2=new Table1();
77 t2.setDate("2010-10-2");
78 t2.setText("开会讨论开发计划");
79 _table1.add(t2);
80
81 dataMap.put("table1", _table1);
82
83 List
84 _table2=new ArrayList
85 ();
86 for(int i=0;i<5;i++)
87 {
88 Table2 _t2=new Table2();
89 _t2.setDetail("测试开发计划"+i);
90 _t2.setPerson("张三——"+i);
91 _t2.setBegindate("2010-10-1");
92 _t2.setFinishdate("2010-10-31");
93 _t2.setRemark("备注信息");
94 _table2.add(_t2);
95 }
96 dataMap.put("table2", _table2);
97 }
98 }
转自/java/514.html
--------------------------------------------------------------------------------
开发一个Word的代码高亮插件
在用Word写技术文档的时候,免不了要在文档中插入一些源代码。

为了使插入进来的源代码更可读,就需要使这些代码的关键字高亮显示。

所以在写这些文档的时候,我经常需要再开一个Visual Studio,在Visual Studio里编辑好代码之后,复制到Word里面,Word会帮助我们保留代码的格式,达到关键字高亮的效果。

但这样做难免有些不方便,如果能在word中装一个支持代码高亮的插件就好了。

在网上搜索无果之后,自己做了一个。

如何开发Word的外接程序是需要解决的第一个问题,可以参考博客园的一个系列:我的VSTO
之路,我就是参考着他这个系列做的这个插件,不过目前这个插件只支持Word 2010。

接下来,怎样实现代码高亮?幸好,有一个开源的项目Wilco.SyntaxHighlighting可以解决我的问题。

它支持多种语言的Highlighter,并提供Html和Rtf两种格式的parser把Highlighter的code 转换为html或rtf的格式。

最后,怎样把高亮后的代码插入到Word中?由于Word的插件开发不是我研究的重点,所以想了一个比较懒的做法,即把html格式或rtf格式的高亮代码复制到剪贴板上,然后利用_Application.Selection.Paste方法粘帖进来,代码如下:
privatevoid button1_Click(object sender, RibbonControlEventArgs e){ var dialog = new MainForm(); if(dialog.ShowDialog() == DialogResult.OK) { dialog.CopyToClipboard(); Globals.ThisAddIn.Application.Selection.Paste(); }}
插件的效果如下。

Word功能区:
点设置按钮弹出设置界面,支持Rtf和Html两种格式,还可以设置边框、背景、交替行等样式,不过我比较懒,没去研究怎么在Rtf格式下设置边框、背景,所以在Rtf格式下是不支持边框颜色、背景颜色和交替行的。

所以建议大家选择Html格式。

设置界面如下图:
点击插入代码按钮,会弹出插入代码的界面,如下图:
可以选择C#、Java、Xml、Javascript等多种语言。

一些效果如下:
//no styleprivatevoid button1_Click(object sender, RibbonControlEventArgs e){ var dialog = new MainForm(); if(dialog.ShowDialog() == DialogResult.OK) { dialog.CopyToClipboard(); Globals.ThisAddIn.Application.Selection.Paste(); }}
1: //框+ 行号2: privatevoid button1_Click(object sender, RibbonControlEventArgs e) 3: { 4: var dialog = new MainForm(); 5: if(dialog.ShowDialog() == DialogResult.OK) 6: { 7: dialog.CopyToClipboard(); 8: Globals.ThisAddIn.Application.Selection.Paste(); 9: } 10: }
1: //框+ 行号+ 交替行2: privatevoid button1_Click(object sender, RibbonControlEventArgs e) 3: { 4: var dialog = new MainForm(); 5: if(dialog.ShowDialog() == DialogResult.OK) 6: { 7: dialog.CopyToClipboard(); 8: Globals.ThisAddIn.Application.Selection.Paste(); 9: } 10: }
我这篇文章就是用Word写的,上面这些代码也是用我做的这个插件插进来的。

但就当我兴高采烈的用Word把这篇文章发布到博客园之后,才发现发布后的上述代码段出现了不同程度的变形,而且是无法接受的变形,如下图:
可以看到,边框没了,private和void之间空格很大,而且还换行了。

这个问题研究了很久和不知道该如何解决,可能Word在发布博文的时候对格式的改变太大,导致了变形。

那如果想把Word写的文章发布到博客上怎么办呢?建议在Word里写好的文章后,把内容复制下来,然后在Windows live writer“选择性粘帖”进去,利用windows live writer来发布博客。

相关文档
最新文档