FreeMarker模板导出word报表

最近遇到了生成报表操作的需求,使用easyExcel导出表格,并不能很好的满足项目需求,所以最终选择了freemarker的方式来导出word报表,网上各种各样的笔记层出不穷,所以此文用来记录自己实际应用的过程。

使用freemarker模板导出word文档大致可分为三步

  1. 制作word模板
  2. 编写生成word文档的工具类
  3. 准备数据,调用模板生成word文档

1.制作模板

1.1打开office-word,创建新的word文档,并编写自己需要的样式,例如:

 1.2编写好样式之后,另存为xml格式

 1.3用相关工具(我用的是notepad++)打开文档并格式化,修改你要填入实际数据的地方

例如:该模板是一个报表表格,有很多行,所以需要在表格前加<#List 实际数据名称 as 数据名称>标签,然后替换相关字段,此处终端一号替换为${dataList。terminalName};是因为我的数据名称为terminalName;

 注:图片则需要将那一大串base64编码(在binData标签中间)修改为相关字段:例如下图

 

也要注意图片的ID,不修改的话会所有图片都长一样!!!!!!!

1.4 完成字段替代后,保存,将文件后缀名修改为.ftl 

1.5 将文件放在项目中:例如下图


2.编写工具类

2.1导入依赖

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

2.2编写工具类

/**
 * @author Lsc
 */
@Component
public class WordUtils {
    /**
     * 生成word
     * @param dataMap
     * @throws Exception
     */
    public void saveWord(Map<String,Object> dataMap) throws Exception {
        Configuration configuration = new Configuration();
        configuration.setDefaultEncoding("UTF-8");
        //模板文件所在路径,此处我将刚才生成的模板放在了resources/templates下
        configuration.setClassForTemplateLoading(this.getClass(), "/templates");
        Template template = configuration.getTemplate("report.ftl", "utf-8");
        //导出文件
        File outFile = new File(commonProperties.getWordPath() + dataMap.get("fileName") +".doc");
        Writer out = null;
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(outFile);
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
            out = new BufferedWriter(outputStreamWriter);
            template.process(dataMap, out);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            out.close();
        }
    }

     /**
     * 将图片转为base64编码
     */
    public String getImgStr(String imgFile){
        //将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        InputStream in = null;
        byte[] data = null;
        //读取图片字节数组
        try
        {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return new String(Base64.encodeBase64(data));
    }


}

3.准备数据,调用工具类

此处为一个测试类,实际生产中放在具体的业务中就可以了,记得字段要和模板统一!

@SpringBootTest(classes = UapApplication.class)
public class FreemarkerTest {

    @Autowired
    private WordUtils wordUtils;
    @Test
    public void test1() throws Exception {
        Map<String,Object> maps = new HashMap<>();
        maps.put("fileName","报表测试111");
        Map<String,String> map = new HashMap<>();
        map.put("terminalName","终端1号");
        map.put("terminalSn","36695sss");
        map.put("time","2021-11-11");
        map.put("result","正常");
        // 图片要转为base64编码才可以正常展示
        map.put("originalImg",wordUtils.getImgStr("C:\\Users\\DELL\\Desktop\\1.png"));
        map.put("identifyImg",wordUtils.getImgStr("C:\\Users\\DELL\\Desktop\\2.png"));
        //因为我的报表列数是根据实际数量变化的,所以这里和模板都用了列表
        List<Map<String,String>> datalist = Lists.newArrayList();
        datalist.add(map);
        datalist.add(map);
        maps.put("dataList",datalist);
        wordUtils.saveWord(maps);
    }

}

最终结果图:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值