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/

相关文章
相关标签/搜索