【技能储备】关于自学FreeMarker导出word的那些事

来源:互联网 发布:淘宝开学季文案 编辑:程序博客网 时间:2024/06/14 03:50

【新技能Get】关于自学FreeMarker导出word的那些事

 

 

       最近,项目中需要做一个导出word文件的功能。

这个,简单!原来在公司就用过一个叫什么什么的软件,网上查找了好久,突然发现是要收费的!!!心如死灰的时候,发现大家都在推荐FreeMarker来做word导出。

找了几篇大神写的文章,对着敲代码,试了一下,发现果真是好用,基本可以实现导出简单字段,动态行的表格什么什么的。

为了巩固一下记忆(看自己的写的习惯一点),决定记录一下学习过程。下面开始上代码,走起!

 

一、前期准备

1、软件环境:Sublime Text2(替Sublime吹嘘一下,这款文本编辑工具功能真的很强大)、Eclipse

2、需要下载的jar包:freemarker2.3.20.jar (也可以去官网看看,我是在站内下载的2.3.20版本。官网地址:http://freemarker.org/)

二、懒得起名字了

代码:

import java.io.BufferedWriter; 

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException; 

import java.io.FileOutputStream; 

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStreamWriter; 

import java.io.Writer; 

import java.util.ArrayList; 

import java.util.HashMap; 

import java.util.List; 

import java.util.Map; 

 

import freemarker.template.Configuration; 

import freemarker.template.Template; 

import freemarker.template.TemplateException; 

 

import sun.misc.BASE64Encoder;

 

/**

 * <P>Title:关于使用FreeMarker导出Word的测试 </p>

 * <P>Description: </p>

 * @author

 * @date

 */

public class Test { 

     

    private Configurationconfiguration = null

     

    public Test(){ 

        configuration = newConfiguration(); 

        configuration.setDefaultEncoding("UTF-8"); 

    } 

     

    public staticvoid main(String[] args) { 

    Test test = new Test(); 

        test.createWord(); 

    } 

     

    public void createWord(){ 

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

        getData(dataMap); 

        configuration.setClassForTemplateLoading(this.getClass(),"/com");  //FTL文件所存在的位置 

        Template t=null

        try

            t = configuration.getTemplate("简历模板.ftl");//文件名 

        } catch (IOExceptione) { 

            e.printStackTrace(); 

        } 

        File outFile = newFile("C:/Users/zpx/Desktop/"+Math.random()*10000+".doc"); 

        Writer out = null

        try

            out = new BufferedWriter(newOutputStreamWriter(new FileOutputStream(outFile))); 

        } catch (FileNotFoundExceptione1) { 

            e1.printStackTrace(); 

        } 

          

        try

            t.process(dataMap,out); 

        } catch (TemplateExceptione) { 

            e.printStackTrace(); 

        } catch (IOExceptione) { 

            e.printStackTrace(); 

        } 

    } 

 

    private void getData(Map<String,Object> dataMap) { 

        dataMap.put("name","张三"); 

        dataMap.put("birthday","1993-07-27"); 

        dataMap.put("telphone","1123123123"); 

        dataMap.put("sex","女");

        dataMap.put("email","sejfis23@154.com");

        dataMap.put("img",getImageStr());

        //dataMap.put("check_box",""==null?"■":"□");

    //Word模板中表格的遍历循环

        List<Userlist> list= new ArrayList<Userlist>(); 

        for (int i= 0; i < 10; i++) { 

          Userlist userlist = new Userlist();

          userlist.setEmpolyeeid(i+""); 

          userlist.setEmpolyeename("内容"+i);

          userlist.setLast_update_by("李四");

          userlist.setLast_update_date("2016-09-15");

            list.add(userlist); 

        } 

         

         

        dataMap.put("list",list); 

}

//对图片进行base64编码

    private String getImageStr(){

        String imgFile ="E:/Photo圖片/img.jpg";

        InputStream in =null;

        byte[] data= null;

        try {

            in = new FileInputStream(imgFile);

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

            in.read(data);

            in.close();

        } catch (IOExceptione) {

            e.printStackTrace();

        }

        BASE64Encoder encoder= new BASE64Encoder();

        return encoder.encode(data);

    }

}

建一个实体类用户列表循环

public class Userlist {

  

      publicString empolyeeid;

  

      publicString empolyeename;

  

      publicString last_update_by;

  

      publicString last_update_date;

 

      publicString getEmpolyeeid() {

         return empolyeeid;

      }

 

      publicvoid setEmpolyeeid(String empolyeeid) {

         this.empolyeeid = empolyeeid;

      }

  

      publicString getEmpolyeename() {

         return empolyeename;

      }

  

      publicvoid setEmpolyeename(String empolyeename) {

         this.empolyeename = empolyeename;

      }

 

      publicString getLast_update_by() {

         return last_update_by;

      }

 

      publicvoid setLast_update_by(String last_update_by) {

         this.last_update_by = last_update_by;

      }

 

      publicString getLast_update_date() {

         returnlast_update_date;

      }

 

      publicvoid setLast_update_date(String last_update_date) {

         this.last_update_date= last_update_date;

      }

}

 

三、模板的制作

怎么说,就是首先做一个word模板(.doc后缀),然后另存为Word2003 XML文档(.xml),这时候就需要用到上面提到的Sublime Test打开另存为的.xml模板了。

第一次打开开到源码的时候都要疯了。(图1)


用Sublime Text的Indent xml插件,可以把代码格式化。

按照你的需求,把你需要替换的标签替换

(图2)

如姓名后面这块你要导出进数据,这时候就需要你去模板.xml文件中相同位置,添加上${name},然后通过程序里面操作流,替换掉这个${name}标签。

 (图3)

到这里,我觉得基本就可以满足一大半的word导出任务了。

然后图片的话,

(图4)

就是红框中的${img}位置本来是有一段好长好长的图片数据流的,用代码中的方法就可以和字段一样替换掉

 

下面就是重中之重,list列表的导入了。

上面的”模板.xml”文件,这时候需要改变后缀为”模板.ftl”,然后还是用Sublime打开,在需要循环展示的代码段外套加上<#list listas userlist></#list>

,标签中的list是代码中拼装的列表展示数据的集合名称,userlist是实体类的名称,都是可以自定义的。

  (图4)

   差不多就是这样,欢迎大家指教!

 

参考资料:http://blog.csdn.net/zhanwentao2/article/details/7255432

      http://blog.csdn.net/cheung1021/article/details/6146239

0 0
原创粉丝点击