使用ftl文件进行导出需要循环的word文档

先将word文档整合,为单个循环的样子,然后将该word文档另存为xml文档,在文件所在位置将其改为ftl后缀文件,然后拖入到idea中进行格式化并修改。

先导入freemarker包

  <properties>
      <freemarker>2.3.30</freemarker>
  </properties>

 <!-- PDF生成组件start -->
<!-- freemarker,生成 html -->
<dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>${freemarker}</version>
</dependency>

工具类

package com.jkr.utils;

import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;

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

public class WordUtil {

    private static final String BASE_PATH = "/templates/";

    private static Map<String, String> TEMPLATE_MAP = new HashMap<String, String>();

    public static String getTemplate(String id) throws IOException {

        String template = TEMPLATE_MAP.get(id);

        if (StringUtils.isBlank(template)) {

            StringBuffer path = new StringBuffer();

            path.append(BASE_PATH).append(id);

            template = inputStream2String(WordUtil.class.getResourceAsStream(path.toString()));

            TEMPLATE_MAP.put(id, template);

        }

        return template;

    }

    /**

     * 将stream 转成字符串

     *

     * @param is

     * @return

     * @throws IOException

     */

    private static String inputStream2String(InputStream is) throws IOException {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        int i = -1;

        while ((i = is.read()) != -1) {

            baos.write(i);

        }

        return baos.toString();

    }



    /**
     * 导出excel
     * @param map word文档中参数
     * @param wordName 为模板的名字  例如xxx.ftl
     * @param name 是临时的文件夹米名称 string类型 可随意定义
     * @throws IOException
     */
    public static File getFileExportMillCertificateWord(Map map, String wordName, String name)throws IOException{
        String source = getTemplate(wordName);

        Configuration cfg = new Configuration(new Version("2.3.23"));

        StringTemplateLoader loader = new StringTemplateLoader();

        loader.putTemplate("", source);

        cfg.setTemplateLoader(loader);

        cfg.setDefaultEncoding("UTF-8");

        Template freemarkerTemplate = cfg.getTemplate("");
        File file = null;
        try {
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(map,freemarkerTemplate,name);
        } finally {
        }
        return file;
    }



    /**
     * 导出excel

     * @param response 响应对象
     * @param map word文档中参数
     * @param wordName 为模板的名字  例如xxx.ftl
     * @param fileName 是word 文件的名字 格式为:"xxxx.doc"
     * @param name 是临时的文件夹米名称 string类型 可随意定义
     * @throws IOException
     */
    public static void exportMillCertificateWord(HttpServletResponse response, Map map, String wordName, String fileName, String name) throws IOException {
        String source = getTemplate(wordName);

        Configuration cfg = new Configuration(new Version("2.3.23"));

        StringTemplateLoader loader = new StringTemplateLoader();

        loader.putTemplate("", source);

        cfg.setTemplateLoader(loader);

        cfg.setDefaultEncoding("UTF-8");

        Template freemarkerTemplate = cfg.getTemplate("");
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        try {
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(map,freemarkerTemplate,name);
            fin = new FileInputStream(file);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/x-download");
            response.setHeader("Content-Disposition", "attachment;filename=" +  new String(java.net.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) {
        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;
    }

}

controller层

@PostMapping(value = "/checkExport")
public void checkExport(HttpServletResponse response, @RequestParam String checkId , @RequestParam Integer dataSources) {
        baseService.checkExport(response, checkId, dataSources);
    }

service层

@Override
    public void checkExport(HttpServletResponse response, String checkId, Integer dataSources) {
        try {
            // 获取检查记录
            Map<String, Object> exportMap = new HashMap<>();
            // 获取要导出的记录信息
            Check check = baseMapper.selectById(checkId);    
            // 将获取的记录放入map中
            exportMap.put("check", check);
            // 处理循环数据的方法(根据需求自己修改,这里不写了)
            exportMap = checkDataProcessing(exportMap, checkId);
            String wordName;
            // 根据传来的字段,判断导出哪个模版
            if(ObjectUtils.isNotEmpty(dataSources) && dataSources.equals(CommonConstant.DATA_SOURCES_2)){
                wordName = "societyRenovate.ftl";
            }else{
                wordName = "superviseInspect.ftl";
            }
            // jdk8中比较安全的时间格式化
            ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(check.getCheckTime().toInstant(), ZoneId.systemDefault());
            LocalDate localDate = zonedDateTime.toLocalDate();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            String checkDate = localDate.format(formatter);
            // 导出的文件命名(根据自己需求获取字段进行处理)
            String fileName = checkDate+"_"+check.getEntName()+"_"+check.getEntTypeAll()+".doc";  //命名
            // 将信息放进工具类处理导出
            WordUtil.exportMillCertificateWord(response, exportMap, wordName, fileName , "name");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在ftl中:

使用:  
1. <w:t>${ check.userName! }</w:t>  
    时间格式化为:<w:t>${(check.checkTime)?string('yyyy-MM-dd')}</w:t>
来进行map中的变量引入(因为上面map传递的名字叫做check),‘!’的作用是判空,如果没有就在word中导出空格(如果可能为空必须写,不然报错)

2.<#if detailList?? && (detailList?size > 0)>
     <#list detailList! as item>
  </#list>
  </#if>
    if语句,其中变量后的‘??’作用是判断是否存在, ‘&&’ 是并且, as 是将集合起别名,之后的detailList为item

3.<w:t>${item_index + 1}</w:t>     
    这样是索引,是排序的 1 - list.size() 

              

 

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我不是一个视觉机器人,无法提供图片。不过,我可以为您提供使用Freemarker导出Word文档的代码实现和总结。 代码实现: 1. 导入相关依赖包 ```java <!--freemarker--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency> <!--poi--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.0</version> </dependency> ``` 2. 编写模板文件Word中编辑好需要导出的文档,并保存为.ftl文件。 3. 实现导出功能 ```java public void export() { // 获取模板文件 String templatePath = "src/main/resources/template.ftl"; File templateFile = new File(templatePath); // 加载模板文件 Configuration configuration = new Configuration(Configuration.VERSION_2_3_28); configuration.setDefaultEncoding("UTF-8"); try { configuration.setDirectoryForTemplateLoading(templateFile.getParentFile()); Template template = configuration.getTemplate(templateFile.getName()); // 定义数据模型,用于模板中填充数据 Map<String, Object> dataMap = new HashMap<>(); dataMap.put("title", "导出文档标题"); dataMap.put("content", "导出文档内容"); // 创建Word文档 XWPFDocument document = new XWPFDocument(); // 填充模板数据 StringWriter writer = new StringWriter(); template.process(dataMap, writer); String content = writer.toString(); IOUtils.closeQuietly(writer); // 将填充好的模板内容写入Word文档中 XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(content); // 保存Word文档 String savePath = "src/main/resources/export.docx"; FileOutputStream outputStream = new FileOutputStream(savePath); document.write(outputStream); IOUtils.closeQuietly(outputStream); } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); } } ``` 总结: 1. Freemarker是一款模板引擎,可以实现将数据填充到模板中生成动态内容。 2. POI是一款开源的Java Office API,可以实现对Word、Excel等Office格式文件的读写操作。 3. Freemarker和POI结合使用,可以实现将动态数据填充到Word模板中并导出Word文档。 4. 在模板中插入图片时,可以在模板中使用<img>标签,然后在代码中将图片添加到Word文档中即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值