【freemarker】使用模板导出word

1. 需求

           每周固定统计一些数据,然后通过 word 的形式将数据导出。


2. 思路

              ①  使用poi 的XWPFDocument 相关 api 操作  word 中的数据 。

                   * 存在的问题  :  在获取 XWPFRun 对象时,对于 run 区域的划分会有问题,有时候会把需要替换的字符 拆分 , 从而导致在替换时找不到而出错 。并没有找到解决的办法

              ②   使用 freemarker 对 ftl 模板文件中的特定字符串替换掉 ,采取此方法     freemarker 官网


3. 具体实现

     

               ★  gradle  引用 jar 包   

compile (
'org.freemarker:freemarker:2.3.20',
)

               ★ 生成 ftl 模板文件 (idea 要作为资源文件存在 resource包中,方便freemarker获取)

                         首先是 .doc 的模板文件 , 将 .doc 中需要动态添加的字段 用特殊字符替换 (如11h等,这样可以防止在另存为ftl文件之后被拆分),然后另存为.xml 文件 ,另存为.ftl文件 ,使用编辑器编辑 ftl 文件 ,将之前特定字符替换成可以被替换的内容(形如${}) 


    ★ 相关代码

WordGenerator  util 类

package com.vastio.util;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

import static com.google.common.io.Resources.getResource;

/**
 * Created by xlch on 2016/4/14.
 */
public class WordGenerator {

    private Map<String,String> replaceMap = null;
    private static Configuration config = null;
    private static Map<String,Template> templateMap = null;

    static {
        config = new Configuration();
        config.setDefaultEncoding("utf-8");
        config.setClassForTemplateLoading(WordGenerator.class,"/com/vastio/ftl"); //官方给出三种方法获取模板文件
        templateMap = new HashMap<String, Template>();
        try {
            Template template = config.getTemplate("report.ftl");
            templateMap.put("template",template);  //存储到map中
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public WordGenerator(Map<String, String> replaceMap) {
        this.replaceMap = replaceMap;
    }

    public void exportWord(Writer out){
        Template template = templateMap.get("template");
        try {
            template.process(replaceMap,out);
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //解决设置名称时的乱码
    public static String processFileName(HttpServletRequest request, String fileNames) {
        String codedfilename = null;
        try {
            String agent = request.getHeader("USER-AGENT");
            if (null != agent && -1 != agent.indexOf("MSIE") || null != agent
                    && -1 != agent.indexOf("Trident")) {// ie

                String name = java.net.URLEncoder.encode(fileNames, "UTF8");

                codedfilename = name;
            } else if (null != agent && -1 != agent.indexOf("Mozilla")) {// 火狐,chrome等


                codedfilename = new String(fileNames.getBytes("UTF-8"), "iso-8859-1");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return codedfilename;
    }
}

controller 请求  (下载word不可以用异步请求)

 /**
     * 下载word
     */
    @RequestMapping(value = "/download",method = RequestMethod.POST)
    public String export(HttpServletRequest request, HttpServletResponse response, @RequestParam("week")String week, RedirectAttributes redirectAttributes){
        int isHasData = wordExportService.exportWord(request,response,week); //通过返回值判断数据库是否有数据是否需要下载 ,但是若可以下载这里往下走会有点问题
        if (isHasData == 1){
            return "redirect:/word/home";
        }else{
            redirectAttributes.addFlashAttribute("isHasData",isHasData);
            redirectAttributes.addFlashAttribute("weekNow",week);
            return "redirect:/word/home";
        }
    }

service  的 exportWord 方法

 /**
     * 生成word并导出
     * @param request
     * @param response
     */
    public int exportWord(HttpServletRequest request, HttpServletResponse response,String week){
        Calendar calendar =  Calendar.getInstance();
        calendar .setTime(DateTimeUtil.strToDate(week,"yyyyMMdd"));
        calendar.add(Calendar.DAY_OF_MONTH,-6);
        String lastWeekBegin = DateTimeUtil.dateToStr(calendar.getTime(),"yyyyMMdd");
        String lastWeekEnd = week;
        Map<String,String> fieldMap = this.modelReplace(lastWeekBegin,lastWeekEnd);
        if (fieldMap == null || fieldMap.size()==0){
            return 0;
        }else{
            WordGenerator generator = new WordGenerator(fieldMap);
            String filename = WordGenerator.processFileName(request,"通报"+lastWeekBegin+"-"+lastWeekEnd+".doc");
            try {
                Writer out =  response.getWriter();
                response.reset();
                response.setContentType("application/msword;charset=utf-8");
                response.setHeader("Content-disposition","attachment;filename="+filename);
                response.setBufferSize(1024);
                generator.exportWord(out);
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return 1;
        }
    }

modelReplace 方法替换模板中的字符

  private Map<String,String> modelReplace(String lastWeekBegin,String lastWeekEnd){
        Map<String,String> fieldMap = new HashMap<String, String>();
    //查询数据存放在map中   
    // 如 fieldMap.put("login_week_dpt", largePlatformAppStaEntity.getIntPf().toString()); //模板中有 形如 ${login_week_dpt},将会替换数据
}




       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 Apache POI 和 FreeMarker 来实现 Word 导出。具体步骤如下: 1. 引入依赖: ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.31</version> </dependency> ``` 2. 编写模板文件,例如 `template.ftl`: ```xml <?xml version="1.0" encoding="UTF-8"?> <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> <w:body> <w:p> <w:r> <w:t>${title}</w:t> </w:r> </w:p> <w:p> <w:r> <w:t>${content}</w:t> </w:r> </w:p> </w:body> </w:document> ``` 3. 编写 Java 代码: ```java import freemarker.template.Configuration; import freemarker.template.Template; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; import java.io.*; import java.util.HashMap; import java.util.Map; public class WordExportUtil { public static void export(Map<String, Object> dataMap, String templatePath, String outputPath) throws Exception { // 1. 创建 Configuration 对象 Configuration configuration = new Configuration(Configuration.VERSION_2_3_31); configuration.setDefaultEncoding("UTF-8"); // 2. 加载模板文件 Template template = configuration.getTemplate(templatePath); // 3. 创建 Word 文档对象 XWPFDocument document = new XWPFDocument(); // 4. 填充数据到 Word 文档中 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8"); template.process(dataMap, outputStreamWriter); outputStreamWriter.flush(); ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(line); } // 5. 输出 Word 文档 FileOutputStream fileOutputStream = new FileOutputStream(outputPath); document.write(fileOutputStream); fileOutputStream.close(); } } ``` 其中,`dataMap` 是模板中需要填充的数据,`templatePath` 是模板文件的路径,`outputPath` 是输出文件的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值