當咱們使用Java生成word文檔時,一般首先會想到iText和POI,這是由於咱們習慣了使用這兩種方法操做Excel,天然而然的也想使用這種生成word文檔。可是當咱們須要動態生成word時,一般不只要可以顯示word中的內容,還要可以很好的保持word中的複雜樣式。這時若是再使用IText和POI去操做,就比如程序員去搬磚同樣痛苦。java
這時候,咱們應該考慮使用FreeMarker的模板技術快速實現這個複雜的功能,讓程序員在喝咖啡的過程當中就把問題解決。實現思路是這樣的:先建立一個word文檔,按照需求在word中填好一個模板,而後把對應的數據換成變量${},而後將文檔保存爲xml文檔格式,使用文檔編輯器打開這個xml格式的文檔,去掉多餘的xml符號,使用Freemarker讀取這個文檔而後替換掉變量,輸出word文檔便可。程序員
具體過程以下:app
1.建立帶有格式的word文檔,將該須要動態展現的數據使用變量符替換。編輯器
2. 將剛剛建立的word文檔另存爲xml格式。this
3.編輯這個XMl文檔去掉多餘的xml標記,如圖中藍色部分spa
4.從Freemarker官網【下載】最新的開發包,將freemarker.jar拷貝到本身的開發項目中。.net
5.新建DocUtil類,實現根據Doc模板生成word文件的方法code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
package
com.favccxx.secret.util;
import
java.io.BufferedWriter;
import
java.io.File;
import
java.io.FileOutputStream;
import
java.io.OutputStreamWriter;
import
java.io.Writer;
import
java.util.Map;
import
freemarker.template.Configuration;
import
freemarker.template.DefaultObjectWrapper;
import
freemarker.template.Template;
import
freemarker.template.TemplateExceptionHandler;
public
class
DocUtil {
privateConfiguration configure =
null
;
publicDocUtil(){
configure=
new
Configuration();
configure.setDefaultEncoding(
"utf-8"
);
}
/**
* 根據Doc模板生成word文件
* @param dataMap Map 須要填入模板的數據
* @param fileName 文件名稱
* @param savePath 保存路徑
*/
publicvoid createDoc(Map<String, Object> dataMap, String downloadType, StringsavePath){
try
{
//加載須要裝填的模板
Templatetemplate =
null
;
//加載模板文件
configure.setClassForTemplateLoading(
this
.getClass(),
"/com/favccxx/secret/templates"
);
//設置對象包裝器
configure.setObjectWrapper(newDefaultObjectWrapper());
//設置異常處理器
configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
//定義Template對象,注意模板類型名字與downloadType要一致
template= configure.getTemplate(downloadType +
".xml"
);
//輸出文檔
FileoutFile =
new
File(savePath);
Writerout =
null
;
out=
new
BufferedWriter(
new
OutputStreamWriter(
new
FileOutputStream(outFile),
"utf-8"
));
template.process(dataMap,out);
outFile.delete();
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
6.用戶根據本身的須要,調用使用getDataMap獲取須要傳遞的變量,而後調用createDoc方法生成所須要的文檔。xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/**
* 根據下載類型獲取須要傳遞的Map參數
* @param oid 對象Id
* @param downloadType 下載類型
*/
private
Map<String, Object> getDataMap(String oid,String downloadType){
Map<String, Object> dataMap =
new
HashMap<String, Object>();
if
(
"Parameter1"
.equals(downloadType)){
...
...
dataMap = DataMapUtil.setObjToMap(Object1);
}
else
{
...
...
dataMap = DataMapUtil.setObjToMap(Object2);
}
return
dataMap;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
public
class
DataMapUtil {
private
static
Map<String, Object> dataMap =
new
HashMap<String, Object>();
/**
* 將對象轉換成Map
* @param obj 對象類
* @return
*/
public
static
Map<String,Object> setObjToMap(Object obj){
Class c;
try
{
c = Class.forName(obj.getClass().getName());
Method[] methods = c.getMethods();
for
(
int
i=
0
,l=methods.length;i<l;i++){
String method = methods[i].getName();
System.out.println(
"The method is:"
+ method);
if
(method.startsWith(
"get"
)){
Object value = methods[i].invoke(obj);
if
(value !=
null
){
if
(value.getClass().getClassLoader() !=
null
){
//處理自定義的對象類型
setObjToMap(value);
}
String key = method.substring(
3
);
key = key.substring(
0
,
1
).toLowerCase() + key.substring(
1
);
if
(
"java.util.Date"
.equals(value.getClass().getName())){
value = DateUtil.dateToString((Date)value);
}
dataMap.put(key, value);
}
}
}
}
catch
(Exception e) {
e.printStackTrace();
}
return
dataMap;
}
}
|
7.趕忙把這個方法,應用到本身的項目中吧。對象
本文出自 「這我的的IT世界」 博客,請務必保留此出處http://favccxx.blog.51cto.com/2890523/1331115