java freemarker 动态生成excel文件

参考文章 http://www.ksqn.cn/news/1333.html

好久木有更新啦

抓住2023的小尾巴

浅浅更新一下吧~

最近做了一个动态生成excel的功能,这里记录下部分功能,主要用到的是freemarker框架,spring就有带,我起的demo载入了一下freemarker的jar包

一、创建模板

首先可以创建一个excel,编辑自己想要的模板,这里举个简单的例子

编写好后可以保存一下,然后再保存为.xml格式的文件,就能得到模板雏形

大概是长这样

然后根据ftl文件的语法,我们可以对模板进行改造,加入自己需要的字段

这里列举一些常见的方式

1、普通字段填充

姓名
${(name)!}

2、日期填充,java传入的参数类型为Date

    出生年月<#if birth??>${birth?string("yyyy-MM-dd")}

3、switch case选择用法

国籍<#if certType??><#switch certType> <#case "A"> ■身份证 □外籍护照 □港澳居民来往内地通行证<#break> <#case "B"> □身份证 ■外籍护照 □港澳居民来往内地通行证<#break> <#case "C"> □身份证 □外籍护照 ■港澳居民来往内地通行证<#break> <#default> <#else>□身份证 □外籍护照 □港澳居民来往内地通行证

4、数组对象展示

(这边我做的这个主要是因为有动态展示的需求,如果没有家属信息,就不展示家属单元格)

   <#list spouseInfos as row>家属信息姓名${(row.name)!}关系${(row.relation)!}联系电话${(row.tel)!}

这里需要注意如果使用了数组动态展示需要计算行数

可以把xml文件里的ExpandedRowCount参数进行修改,加入totalRowCount参数标记行数

在java程序中需要动态计算这个行数

 

模板制作好以后保存再修改文件格式名称为.ftl即可

主体部分为

  
基本信息姓名${(name)!}性别${(sex)!}出生年月<#if birth??>${birth?string("yyyy-MM-dd")}其他信息国籍<#if certType??><#switch certType> <#case "A"> ■身份证 □外籍护照 □港澳居民来往内地通行证<#break> <#case "B"> □身份证 ■外籍护照 □港澳居民来往内地通行证<#break> <#case "C"> □身份证 □外籍护照 ■港澳居民来往内地通行证<#break> <#default> <#else>□身份证 □外籍护照 □港澳居民来往内地通行证居住地址${(address)!}联系电话${(tel)!}<#list spouseInfos as row>家属信息姓名${(row.name)!}关系${(row.relation)!}联系电话${(row.tel)!}

二、生成文件

生成文件的主要java代码如下

import freemarker.template.Configuration;
import freemarker.template.Template;import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;public class ExcelUtil {/*** 根据模板生成文件* @param dataMap           写入数据* @param templateFilePath  模板文件路径* @param outFileName       输出文件路径*/public static void doGenerateFile(Map dataMap, String templateFilePath, String outFileName) {Writer out = null;FileOutputStream fileStream = null;//需要压缩的文件,大于1个才会压缩try {//生成合同文件Configuration configuration = new Configuration();configuration.setDefaultEncoding("UTF-8");Template t = configuration.getTemplate(templateFilePath); // 获取模板文件// 导出文件File outFile = new File(outFileName);//获取父目录File fileParent = outFile.getParentFile();//判断是否存在if (!fileParent.exists()) {//创建父目录文件fileParent.mkdirs();}OutputStreamWriter oWriter = null;fileStream = new FileOutputStream(outFile);oWriter = new OutputStreamWriter(fileStream, StandardCharsets.UTF_8);out = new BufferedWriter(oWriter);// 将填充数据填入模板文件并输出到目标文件t.process(dataMap, out);} catch (Exception e1) {if (fileStream != null && out != null) {close(fileStream, out);}System.out.println("生成文件出错," + e1.getMessage());} finally {if (fileStream != null && out != null) {close(fileStream, out);}}}private static void close(FileOutputStream fileStream, Writer out) {try {fileStream.flush();fileStream.close();out.flush();out.close();} catch (Exception e) {System.out.println("关闭流异常," + e.getMessage());}}public static Date str2Date(String dateString) {try {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date date = sdf.parse(dateString);return date;} catch (Exception e) {e.printStackTrace();}return null;}
}

写个简单的类测试一下

1、如果不需要展示List对象的数据,可以存一个空数组到Map,本文为例,家属信息为列表对象


import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class TestMain {public static void main(String[] args) {//相对路径 模板文件、输出文件String templateFile = "file/temp.ftl";String outFileName = "file/test.xls";Map dataMap = test01();
//        Map dataMap = test02();try {ExcelUtil.doGenerateFile(dataMap, templateFile, outFileName);} catch (Exception e) {System.out.println("处理异常," + e.getMessage());}}private static Map test01() {Map dataMap = new HashMap<>();BigDecimal baseRow = new BigDecimal(6);dataMap.put("name", "张三");dataMap.put("sex", "男");dataMap.put("birth", ExcelUtil.str2Date("1990-01-10"));dataMap.put("certType", "A");dataMap.put("address", "地址详情");dataMap.put("tel", "110110");
//放入一个空数组的参数避免合成的时候报错List> list = new ArrayList<>();dataMap.put("spouseInfos", list);dataMap.put("totalRowCount", baseRow);return dataMap;}private static Map test02() {Map dataMap = new HashMap<>();BigDecimal baseRow = new BigDecimal(6);dataMap.put("name", "张三");dataMap.put("sex", "男");dataMap.put("birth", ExcelUtil.str2Date("1990-01-10"));dataMap.put("certType", "A");dataMap.put("address", "地址详情");dataMap.put("tel", "110110");List> list = new ArrayList<>();Map s1 = new HashMap<>();s1.put("name", "李四");s1.put("relation", "夫妻");s1.put("tel", "112112");list.add(s1);dataMap.put("spouseInfos", list);//计算展示行数BigDecimal subtract = baseRow.add(new BigDecimal(3));dataMap.put("totalRowCount", subtract);return dataMap;}
}

使用test01数据效果如图

使用test02数据效果如图

你可能感兴趣的:(java,excel,python)