使用freemarker生成带颜色填充的excel表格文件

使用freemarker生成带颜色填充的excel表格文件

首页休闲益智颜色填充3D更新时间:2024-05-09

最近接了个需求,大致是生成一个excel文件,这个文件里面部分内容是动态填充的,并且有些表格还是根据内容的数据大小进行颜色背景填充。看到excel首先想到的是poi,业内还有Easy Excel(阿里开源的)框架,不过笔者先前刚搞了freemarker,就考虑使用freemarker来解决这个问题了,使用freemarker有几个步骤,首先要制作模板,编写ftl语言代码,然后再java代码中生成填充变量,直接生成文件即可。下面给一个类似的需求,要求生成一个excel,里面包含某用户的体检信息如下图,要求体重超过80kg表格背景色变为橙色,心率超过100表格背景色为红色。

样例展示

下面介绍步骤:

1.制作excel模板,先造一个变量填充的模板,先建一个如下图的xlsx文件;

2.将该文件另存为一个xml文件;

3.解读分析xml文件,可以用notepad 打开;找到下xml代码的位置,身高我们用了橙色背景,此处样式id是s52,体重用了红色背景,此处样式id是s53,序号和心率没有背景色样式id是s51,因此我们猜测到这个样式在其他处有定义颜色(事实也是如此);

注意:样式id不一定和我的一样,所以要改为自己的id。

<#--样式id引用--> <Row ss:StyleID="s50"> <Cell ss:StyleID="s51"> <Data ss:Type="String">序号</Data> </Cell> <#--橙色s52--> <Cell ss:StyleID="s52"> <Data ss:Type="String">身高</Data> </Cell> <#--红色s53--> <Cell ss:StyleID="s53"> <Data ss:Type="String">体重</Data> </Cell> <Cell ss:StyleID="s51"> <Data ss:Type="String">心率</Data> </Cell> </Row>

<#--样式id定义--> <Style ss:ID="s51"> <Alignment ss:Horizontal="Center" ss:Vertical="Center"/> </Style> <Style ss:ID="s52"> <Alignment ss:Horizontal="Center" ss:Vertical="Center"/> <Interior ss:Color="#FFC000" ss:Pattern="Solid"/> </Style> <Style ss:ID="s53"> <Alignment ss:Horizontal="Center" ss:Vertical="Center"/> <Interior ss:Color="#FF0000" ss:Pattern="Solid"/> </Style>

4.编写ftl文件:我们可以先复制一份xml文件避免改错。首先我们将表头都改为无背景色,然后将下面变量写ftl的判断,符合条件为有颜色,不符合无颜色填充;同时为了能分辨出来条件判断有效,我们下面多做几行数据,即为一个list,恰好可以学习下ftl文件里list遍历;

<#--样式id引用, 表头都改为无背景色s51--> <Row ss:StyleID="s50"> <Cell ss:StyleID="s51"> <Data ss:Type="String">序号</Data> </Cell> <Cell ss:StyleID="s51"> <Data ss:Type="String">身高</Data> </Cell> <Cell ss:StyleID="s51"> <Data ss:Type="String">体重</Data> </Cell> <Cell ss:StyleID="s51"> <Data ss:Type="String">心率</Data> </Cell> </Row>

<#--list判空--> <#if list?? && (list?size>0)> <#--遍历list--> <#list list as item> <Row ss:StyleID="s50"> <Cell ss:StyleID="s51"> <Data ss:Type="number">${item_index 1}</Data> </Cell> <Cell ss:StyleID="s51"> <Data ss:Type="String">${item.high}</Data> </Cell> <#--string声明为number--> <#assign weightNum = item.weight?number> <#if weightNum <= 80 > <#-- 小于80无颜色--> <Cell ss:StyleID="s51"> <Data ss:Type="String">${item.weight}</Data> </Cell> <#else > <#-- 大于80橙色--> <Cell ss:StyleID="s52"> <Data ss:Type="String">${item.weight}</Data> </Cell> </#if> <#assign heartNum = item.heart?number> <#if heartNum <= 100 > <#-- 小于100无颜色--> <Cell ss:StyleID="s51"> <Data ss:Type="String">${item.heart}</Data> </Cell> <#else > <#-- 大于100红色--> <Cell ss:StyleID="s53"> <Data ss:Type="String">${item.heart}</Data> </Cell> </#if> </Row> </#list> </#if>

5.将上述复制修改后的xml文件另存为ftl后缀文件;

6.编写java代码,输出文档,代码如下

import lombok.Builder; import lombok.Data; @Data @Builder public class User { private Integer high; private String weight; private String heart; }

import com.google.common.collect.Lists; import freemarker.template.Configuration; import freemarker.template.Template; import org.apache.commons.codec.CharEncoding; import java.io.*; import java.text.SimpleDateFormat; import java.util.*; public class FTLDemo { public static void main(String[] args) { HashMap<String, Object> param = new HashMap<>(); param.put("name","周星星"); param.put("time",new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date())); User user1 = User.builder().high(180).weight("120").heart("180").build(); User user2 = User.builder().high(168).weight("50").heart("60").build(); List<User> users = Lists.newArrayList(user1, user2); param.put("list",users); // todo 此处模板放置路径和生成文件路径修改成自己的 crateFile(param, "C:\\体检模板.ftl","C:\\genetate\\generate.xlsx"); } /** * 将数据渲染到ftl生成文件 * @param dataMap 最外层数据 * @param templatePath ftl绝对路径 * @param targetFile 生成文件文档绝对路径 */ public static void crateFile(Map<String, Object> dataMap, String templatePath, String targetFile){ // 获取ftl的文件路径 String directoryForTemplate = templatePath.substring(0,templatePath.lastIndexOf(File.separator) 1); String templateName = templatePath.substring(templatePath.lastIndexOf(File.separator) 1); try (FileOutputStream out = new FileOutputStream(targetFile); Writer writer = new BufferedWriter(new OutputStreamWriter(out, CharEncoding.UTF_8))){ Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); configuration.setDefaultEncoding(CharEncoding.UTF_8); configuration.setDirectoryForTemplateLoading(new File(directoryForTemplate)); //加载模板 Template template = configuration.getTemplate(templateName); //渲染模板 template.process(dataMap, writer); } catch (Exception e){ e.printStackTrace(); } } }

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

即可生成符合条件的文件。

大家可以自己去试试,ftl里用到了不少语法,如内置的index索引加1作为序号,list的判空以及遍历,还有字符串转数字if判断等。总之这种方法就是需要分析要生成的文件,使用ftl语言修改模板,最后给出填充数据代码一键生成,还是比较方便的。希望这篇文章能给你一些灵感或启发,欢迎评论,都会回复。感谢观看!

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved