freemarker导出word文档

    公司要求添加一个导出文档功能,翻了下百度,找到一个freemarker好东西。话不多说,继续

1、新建一个word文档,格式为2003的,就是doc结尾(docx没试)

freemarker导出word文档_第1张图片
简单弄了一个带循环的

2、另存为xml格式

注意了,是另存为,不是直接改后缀,楼主在这上面跌过坑

3、将xml文件的扩展名直接改为ftl

4、循环的兄弟还要用editplus之类的打开ftl文件

添加<#list userList as user>
这句话就相当于把list userList 循环遍历,每一项是user,类似于

forEach items='userList' var='user'>

怎么加,搜 w:tr ,找到你要循环的部分,然后把它包裹起来
freemarker导出word文档_第2张图片
注意我圈出来的东西,这个相当于for循环中的i+1

接下来就是代码,没啥好说的

测试类

我非全复制,所以注意点
这个是别人的下载到指定文件夹中的路径

@Test  
   public void exportSimpleWord() throws Exception{  
       // 要填充的数据, 注意map的key要和word中${xxx}的xxx一致  
      Map dataMap = new HashMap();  
      dataMap.put("username", "张三");  
      dataMap.put("sex", "男");  

    //Configuration用于读取ftl文件  
      Configuration configuration = new Configuration();  
      configuration.setDefaultEncoding("utf-8");  

      /*以下是两种指定ftl文件所在目录路径的方式, 注意这两种方式都是 
       * 指定ftl文件所在目录的路径,而不是ftl文件的路径 
       */  
      //指定路径的第一种方式(根据某个类的相对路径指定)  
      //configuration.setClassForTemplateLoading(this.getClass(),"");  

      //指定路径的第二种方式,我的路径是C:/a.ftl  
      configuration.setDirectoryForTemplateLoading(new File("C:/"));
       // 输出文档路径及名称  
     File outFile = new File("D:/test.doc");  

     //以utf-8的编码读取ftl文件  
     Template t =  configuration.getTemplate("a.ftl","utf-8");  
     Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"),10240);  
        t.process(dataMap, out);  
        out.close();  
   }  

可能出现的问题1:

当然你自己获取数据可能是List,我们不管他,也这么放进map,可定义为Map,然后运行时出现
Don't know how to present an object of this type to a template: com.vixuan.pojo.Animals巴拉巴拉的一串,我百度了一下,这句话的意思是:
1、无法引述动物类对象到模版,也就是说模板不认识list里面的数据是Animals对象,所以无法通过animals.name来访问属性对象
2、这个是发生在写入word时候
网上的大牛还是很多的,直接给出了答案:
通过查询API文档,可以容易看到Template.process()函数有两种形式,一个是含有两个参数的,而另一个则含有三个参数,他们分别为:

void freemarker.template.Template.process(Object dataModel, Writer out) throws TemplateException,IOException 

void freemarker.template.Template.process(Object dataModel, Writer out, ObjectWrapper wrapper) throws TemplateException, IOException

其实二者没什么大的区别,只是第二个方法比第一个多增加了一个ObjectWrapper wrapper参数而已,那个增加这个参数有什么作用呢?
答案是:第一个方法中默认了ObjectWrapper wrapper参数是ObjectWrapper.SIMPLE_WRAPPER型的,但是在我们的情况下需要另一种类型,也即:ObjectWrapper.BEANS_WRAPPER,观看英文单词也理解是什么意思了吧
所以,改成t.process(dataMap, out,ObjectWrapper.BEANS_WRAPPER);就可以了

可能出现的问题2:

模版类的放置问题,万年的百度告诉我们模版有三种放置方法

//3种方法分别是:
public void setClassForTemplateLoading(Class clazz, String pathPrefix);
public void setDirectoryForTemplateLoading(File dir) throws IOException;
public void setServletContextForTemplateLoading(Object servletContext, String path);

第二、第三种没啥好说的。
第二种基于文件系统, 比如加载/home/user/template下的模板文件。

Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new         File("/home/user/template"));
cfg.getTemplate("Base.ftl");

这样就获得了/home/user/template/Base.ftl这个模板文件。

第三种基于web project。 第二个参数是基于WebRoot下的。
比如: setServletContextForTemplateLoading(context, "/ftl")
就是 /WebRoot/ftl目录。

第一种基于类路径的方法有点小坑

Configuration cfg = new Configuration();
cfg.setClassForTemplateLoading(FreemarkerUtil.class, "/template");
cfg.getTemplate("Base.ftl");

其中FreemarkerUtil所在的包路径是: org.foo.util
那么获得是模板文件就是 ${projectPath}/org/foo/util/template 。
这里注意一下第二个参数需要以 “/” 开头。

通过浏览器下载

网上有许多教程都是下载指定路径,,,,但是耐心找也能发现直接调用浏览器的

//前面map放入数据的部分就不写了
Configuration configuration = new Configuration();  
        configuration.setDefaultEncoding("utf-8");  
        configuration.setClassForTemplateLoading(this.getClass(),""); 
        response.setContentType("application/msword");     
        String fileName = "你好.doc";//文件名
        response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(fileName.getBytes("GBK"), "iso8859-1") + "\"");  
        response.setCharacterEncoding("utf-8");//此句非常关键,不然word文档全是乱码  
        PrintWriter out = response.getWriter();  
       Template t =  configuration.getTemplate("wordDemo.ftl","utf-8");//以utf-8的编码读取ftl文件  
       t.process(dataMap, out,ObjectWrapper.BEANS_WRAPPER);  //因为我当时写的有bean类
       out.close(); 

可能出现的问题3:

如果出现这个

freemarker.core.ParseException: Encountered "<" at line 3, column 28888 in test.ftl.  
Was expecting one of:  
     ...  
     ...  
    "false" ...  
    "true" ...  
     ...  
     ...  
    "." ...  
    "+" ...  
    "-" ...  
    "!" ...  
    "[" ...  
    "(" ...  

这是由于在写${xxx}表达式的时候, xxx与其前方的文字样式不一致, 在另存为xml后你可以搜索一下 "${" , 会发现如下图这种情况:
freemarker导出word文档_第3张图片

参考文档

感谢网上大牛的无私奉献
1、http://blog.csdn.net/zhouzhiwengang/article/details/46352107
2、http://blog.csdn.net/pengyufight/article/details/53125818

你可能感兴趣的:(java导出word,excel)