freemaker 导出word

Posted liudong2

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了freemaker 导出word相关的知识,希望对你有一定的参考价值。

1、打开word

技术分享图片

需求是什么样子就把word画成什么样,然后需要传的参数就写成类似于关键字这种,后边有用。

2、画完word把文档保存成xml结尾的文件

技术分享图片

然后找到这个文件再改为ftl后缀的ftl文件,放到项目的resources下 资源目录

技术分享图片

ftl的文件内容一定是压缩过的,类似于下边这种,下边有应付这种代码的方法技术分享图片

 

3、这时候我们引入maven依赖

 <dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>

 

4、然后将WordGenerator类放进项目里

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStreamWriter; 
import java.io.Writer; 
import java.util.HashMap; 
import java.util.Map; 
import freemarker.template.Configuration; 
import freemarker.template.Template; 

public class WordGenerator { 
private static Configuration configuration = null; 
private static Map<String, Template> allTemplates = null; 

static { 
configuration = new Configuration(); 
configuration.setDefaultEncoding("utf-8"); 
configuration.setClassForTemplateLoading(WordGenerator.class, "/ftl"); 
allTemplates = new HashMap<String, Template>(); 
try { 
allTemplates.put("juece", configuration.getTemplate("juecelian.ftl")); 
} catch (IOException e) { 
e.printStackTrace(); 
throw new RuntimeException(e); 
} 
} 

private WordGenerator() { 
throw new AssertionError(); 
} 

public static File createDoc(Map<?,?> dataMap, String type,String fname) { 
String name = fname + ".doc"; 
File f = new File(name); 
Template t = allTemplates.get(type); 
try { 
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开 
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8"); 
t.process(dataMap, w); 
w.flush();
w.close(); 
} catch (Exception ex) { 
ex.printStackTrace(); 
throw new RuntimeException(ex); 
} 
return f; 
} 
 

 5、然后我们把要传递到word上的参数放到一个map里面,传递到ftl里面,这时候我们一开始在word上写的10001、10002就有作用了,假如我们标题写的是10001,那我们就可以eclipse或者idea在ftl里快速找到10001所在的位置,然后把10001替换成${title!‘‘},!‘‘意思是如果为空就在word上输出空字符串,如果搜索没有找到10001也不要慌张,那样你就搜索标题两个字找到了再找距离标题两个字最近的一个<w:t></w:t>中间应该会有1或者10替换成${title!‘‘},再找到剩下的那个0001或者001删掉,大多情况都会找到10001的,集合的话就在

在ftl文件里找表格的最后一个 上边是手机号码,然后我们搜索然后我们在手机号码最近的一个</w:tr>和</w:tr>中间加一行<#list vehicleScheduling as key>vehicleScheduling是集合名称,通过key我们可以${key.title!‘‘}拿到集合里所有的数据,集合循环完毕之后加上</#list>就好

    @RequestMapping(value = "exportWord",method = { RequestMethod.GET,
            RequestMethod.POST })
    @ResponseBody
    public void exportWord(String id,HttpServletRequest request,HttpServletResponse response) throws Exception{
        Map<String, Object> map = new HashMap<String, Object>();
        List<AllocationPlan> sn = new ArrayList<AllocationPlan>();//省内
        List<AllocationPlan> sw = new ArrayList<AllocationPlan>();//省外
        String url = EnvUtil.getVal(EMCY_DECISIONLINKAGE_SERVICE) + "/decisionLinkageService/queryById/" + id;
        String forObject = restService.getForObject(url);
        DecisionLinkage jsonString = JSON.parseObject(forObject,DecisionLinkage.class);
        String title = jsonString.getTitle();//标题
        String createUserName = jsonString.getCreateUserName();//录入人
        String emergencyName = jsonString.getEmergencyName();//应急事件
        String type = jsonString.getType();//决策类型
        String workPlan = jsonString.getWorkPlan();//工作计划
        String remark = jsonString.getRemark();//备注
        map.put("title", title);
        map.put("createUserName", createUserName);
        map.put("emergencyName", emergencyName);
        map.put("workPlan", workPlan);
        map.put("remark", remark);
        if(type == "1"){
            map.put("type", "物资调拨");
        }else{
            map.put("type", "工作安排");
        }
        List<AllocationPlan> allocationPlan = jsonString.getAllocationPlan();//循环
        for (AllocationPlan a : allocationPlan) {
            if(a.getCategory().equals("1")) {//省内
                sn.add(a);
            }else {//
                sw.add(a);
            }
        }
        if(sn.size()==0) {
            sn.add(new AllocationPlan());
        }
        if(sw.size()==0) {
            sw.add(new AllocationPlan());
        }
        map.put("sw",sw);
        map.put("sn",sn);
        
        
        File file = null;
        InputStream fin = null;
        response.setCharacterEncoding("utf-8");
        ServletOutputStream out = response.getOutputStream();
        try {
            file = WordGenerator.createDoc(map, "juece",title);
            fin = new FileInputStream(file);
            response.setContentType("application/msword");
            response.setHeader( "Content-Disposition", "attachment;filename=" + new String(title.getBytes("gb2312"), "ISO8859-1" )+".doc"); 
            response.setCharacterEncoding("utf-8");
            byte[] buffer = new byte[512]; 
            int bytesToRead = -1;
            while ((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        }finally {
            if (fin != null)
                fin.close();
            if (out != null)
                out.flush();
                out.close();
            if (file != null)
                file.delete(); 
        }
    }

6、最后可以通过url?id直接请求到我们的word了

以上是关于freemaker 导出word的主要内容,如果未能解决你的问题,请参考以下文章

使用freemaker 导出word 含多张图片,若无图片则显示文本信息

easypoi根据模板导出word

freemaker 快速入门

Word 文档的优秀代码片段工具或插件?

java poi xwpf操作word生成一个表格怎么合并单元格,求大神指导!

PHP导出excel word的代码