Java實現用Freemarker完美導出word文檔(帶圖片)

前言java

最近在項目中,因客戶要求,將頁面內容(如合同協議)導出成word,在網上翻了好多,感受太亂了,不過最後仍是較好解決了這個問題。web

準備材料數組

1.word原件 2.編輯器(推薦Firstobject free XML editor)瀏覽器

實現步驟app

1.用Microsoft Office Word打開word原件;webapp

2.把須要動態修改的內容替換成***,若是有圖片,儘可能選擇較小的圖片幾十K左右,並調整好位置;編輯器

3.另存爲,選擇保存類型Word 2003 XML 文檔(*.xml)【這裏說一下爲何用Microsoft Office Word打開且要保存爲Word 2003XML,本人親測,用WPS找不到Word 2003XML選項,若是保存爲Word XML,會有兼容問題,避免出現導出的word文檔不能用Word 2003打開的問題】;工具

4.用Firstobject free XML editor打開文件,選擇Tools下的Indent【或者按快捷鍵F8】格式化文件內容。左邊是文檔結構,右邊是文檔內容;學習

5. 將文檔內容中須要動態修改內容的地方,換成freemarker的標識。其實就是Map<String, Object>中key,如${landName};編碼

6.在加入了圖片佔位的地方,會看到一片base64編碼後的代碼,把base64替換成${image},也就是Map<String, Object>中key,值必需要處理成base64;

代碼如:<w:binData w:name="wordml://自定義.png" xml:space="preserve">${image}</w:binData>

注意:「>${image}<」這尖括號中間不能加任何其餘的諸如空格,tab,換行等符號。

若是須要循環,則使用:<#list maps as map></#list>  maps是Map<String, Object>中key,值爲數組,map爲自定義;

7. 標識替換完以後,模板就弄完了,另存爲.ftl後綴文件便可。注意:必定不要用word打開ftl模板文件,不然xml內容會發生變化,致使前面的工做白作了。

代碼實現

工具類WordUtils.Java

?

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

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStreamWriter;

import java.io.Writer;

import java.net.URLEncoder;

import java.util.Date;

import java.util.Map;

 

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import freemarker.template.Configuration;

import freemarker.template.Template;

 

public class WordUtils {

  //配置信息,代碼自己寫的仍是很可讀的,就不過多註解了

 private static Configuration configuration = null;

 //這裏注意的是利用WordUtils的類加載器動態得到模板文件的位置

 // private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/templetes/";

 private static final String templateFolder = "H:/個人項目/lm/lm/web/src/main/webapp/WEB-INF/templates";

 static {

  configuration = new Configuration();

  configuration.setDefaultEncoding("utf-8");

  try {

   configuration.setDirectoryForTemplateLoading(new File(templateFolder));

  } catch (IOException e) {

   e.printStackTrace();

  }

 }

  

 private WordUtils() {

  throw new AssertionError();

 }

  

 public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map,String title,String ftlFile) throws IOException {

  Template freemarkerTemplate = configuration.getTemplate(ftlFile);

  File file = null;

  InputStream fin = null;

  ServletOutputStream out = null;

  try {

   // 調用工具類的createDoc方法生成Word文檔

   file = createDoc(map,freemarkerTemplate);

   fin = new FileInputStream(file);

  

   response.setCharacterEncoding("utf-8");

   response.setContentType("application/msword");

   // 設置瀏覽器如下載的方式處理該文件名

   String fileName = title+DateUtil.formatDateDetailTime(new Date()) + ".doc";

   response.setHeader("Content-Disposition", "attachment;filename="

     .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));

  

   out = response.getOutputStream();

   byte[] buffer = new byte[512]; // 緩衝區

   int bytesToRead = -1;

   // 經過循環將讀入的Word文件的內容輸出到瀏覽器中

   while((bytesToRead = fin.read(buffer)) != -1) {

    out.write(buffer, 0, bytesToRead);

   }

  } finally {

   if(fin != null) fin.close();

   if(out != null) out.close();

   if(file != null) file.delete(); // 刪除臨時文件

  }

 }

  

 private static File createDoc(Map<?, ?> dataMap, Template template) {

  String name = "sellPlan.doc";

  File f = new File(name);

  Template t = template;

  try {

   // 這個地方不能使用FileWriter由於須要指定編碼類型不然生成的Word文檔會由於有沒法識別的編碼而沒法打開

   Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");

   t.process(dataMap, w);

   w.close();

  } catch (Exception ex) {

   ex.printStackTrace();

   throw new RuntimeException(ex);

  }

  return f;

 }

}

Action

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

@RequestMapping("/exportSellPlan")

 public @ResponseBody void exportSellPlan(Long id){

  Calendar calendar = Calendar.getInstance();// 取當前日期。

  if(id!=null){

   SellPlan plan=sellService.getSellPlanInfo(id);

    //得到數據

   Map<String, Object> map = new HashMap<String, Object>();

   map.put("bYear", plan.getBusinessYear()!=null?plan.getBusinessYear():"");

   map.put("lYear", plan.getLiveYear()!=null?plan.getLiveYear():"");

   map.put("leader",plan.getLeader()!=null?plan.getLeader():"");

   map.put("phone", plan.getPhone()!=null?plan.getPhone():"");

   map.put("curYear", calendar.get(Calendar.YEAR)+"");

   map.put("image", getImageBase(plan.getPositionImage()));

   try {

    WordUtils.exportMillCertificateWord(getRequest(),getResponse(),map,"方案","sellPlan.ftl");

   } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

   }

  }

 }

Base64處理

?

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

//得到圖片的base64碼

 @SuppressWarnings("deprecation")

 public String getImageBase(String src) {

  if(src==null||src==""){

   return "";

  }

  File file = new File(getRequest().getRealPath("/")+src.replace(getRequest().getContextPath(), ""));

  if(!file.exists()) {

   return "";

  }

  InputStream in = null;

  byte[] data = null;

  try {

   in = new FileInputStream(file);

  } catch (FileNotFoundException e1) {

   e1.printStackTrace();

  }

  try {

   data = new byte[in.available()];

   in.read(data);

   in.close();

  } catch (IOException e) {

   e.printStackTrace();

  }

  BASE64Encoder encoder = new BASE64Encoder();

  return encoder.encode(data);

 }

Javascript

?

1

window.location.href="<%=path%>/exportSellPlan?id=" rel="external nofollow" + id;

結束語

若是對Freemarker標籤不熟的,能夠在網上先學習下,瞭解文檔結構。

相關連接

Firstobject free XML editor下載地址:http://www.firstobject.com/dn_editor.htm

freemarker 官網:http://freemarker.org/

相關文章
相關標籤/搜索