freemarker模板替换生成word
工具类
public static void createWord(Map<String,Object> dataMap, String templateName, String filePath, String fileName){
try {
//创建配置实例
Configuration configuration = new Configuration();
//设置编码
configuration.setDefaultEncoding("UTF-8");
//设置编码
//configuration.setDefaultEncoding("UTF-8");
//ftl模板文件统一放至 com.lun.template 包下面
//configuration.setClassForTemplateLoading(this.getClass(), "com.jesims.modules.freemarker.entity");
//request.getSession().getServletContext().getRealPath("/WEB-INF/ftl") 获取文件夹下面的所有模版
// configuration.setDirectoryForTemplateLoading(new File(request.getSession().getServletContext().getRealPath("/WEB-INF/ftl")));
configuration.setDirectoryForTemplateLoading(new File("C:\\Users\\18300\\Desktop\\aaa"));// 本地模板路径
//获取模板
Template template = configuration.getTemplate(templateName);
//输出文件
File outFile = new File(filePath+File.separator+fileName);
//如果输出目标文件夹不存在,则创建
if (!outFile.getParentFile().exists()){
outFile.getParentFile().mkdirs();
}
//将模板和数据模型合并生成文件
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
//生成文件
template.process(dataMap, out);
//关闭流
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
调用


一对一传值

集合传值

注:集合传值中也可以返回一个集合,在调用的时候放到map中去,获取值的方式是${别称dian集合的实体类中对于的属性},但有个前提 属性的类型都得是String类型的 不然就报错
模板内增加占位符

注:占位符随意填写,自己能分清就行,没必要和后台的map保持绝对一致
一对一

集合


注:感叹号的意思是其值为null 的话 不报错,
结果如下:
1.一对一的

2.表格

在写的时候遇到了两个问题:
问题1:

本来以为这是两个表格,但其实是一个。要知道既然是一个表 那么他们的key值就不能一样
刚开始是这么写的 出现了上述问题 就是对于不上 因为第一年循环的时候 后面的值都是空的
其中的a是年份循环的下标

解决问题:
在年份循环的外面
//统计map
Map<Integer,Map> sumMap = new HashMap<>();
//记录最大值
int max= 0;
加上这两行代码主要是为了统计map;


具体代码如下:
private ArrayList<Map<String, String>> topTenInflows(String companyId) {
ArrayList<Map<String, String>> result = new ArrayList<>();
// 创建对象
DueDiligenceReport dueDiligenceReport=new DueDiligenceReport();
//设置companyId
dueDiligenceReport.setCompanyId(companyId);
List<String> years = this.towYearList(companyId);
//统计map
Map<Integer,Map> sumMap = new HashMap<>();
//记录最大值
int max= 0;
for (int a = 0; a < years.size(); a++) {
//设置年份
dueDiligenceReport.setYears(years.get(a));
//查询前十大流入
List<DueDiligenceReport> topTenInflowsList = dueDiligenceReportDao.topTenInflows(dueDiligenceReport);
// 流入总金额的初始值
BigDecimal transactionAmountSums = new BigDecimal(0);
// 判断流入集合是否有数据
if (topTenInflowsList.size()>0) {
// 计算流入金额的总和
for (DueDiligenceReport list : topTenInflowsList) {
BigDecimal transactionAmountSum = list.getTransactionAmountSum();
transactionAmountSums = transactionAmountSum.add(transactionAmountSums);
}
for (int i = 0; i < topTenInflowsList.size(); i++) {
// 循环显示标题下对应的数据
Map<String,String> map=new HashMap<>();
// 获取流入金额
BigDecimal transactionAmountSum = topTenInflowsList.get(i).getTransactionAmountSum();
// 单个除以总和 四舍五入 保留两位小数 乘以100
BigDecimal divide = transactionAmountSum.divide(transactionAmountSums, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
// 给算出的百分比拼接百分号
String proportion = divide + "%";
// 关系
List<String> relationshipLabel = dueDiligenceReportDao.getRelationshipLabel(dueDiligenceReport);
if (relationshipLabel.size()>0){
topTenInflowsList.get(i).setRelationshipLabel(relationshipLabel.get(0));
}else {
topTenInflowsList.get(i).setRelationshipLabel("");
}
if (a==0){
map.put("counterpartyAccountName",topTenInflowsList.get(i).getCounterpartyAccountName());
map.put("relationshipLabel",topTenInflowsList.get(i).getRelationshipLabel());
map.put("transactionAmountSum",topTenInflowsList.get(i).getTransactionAmountSum().toString());
map.put("proportion",proportion);
if (max < i){
max = i;
}
sumMap.put(i,map);
}else {
if(sumMap.get(i)!=null){
map=sumMap.get(i);
}
if (max < i){
max = i;
}
map.put("counterpartyAccountName2",topTenInflowsList.get(i).getCounterpartyAccountName());
map.put("relationshipLabel2",topTenInflowsList.get(i).getRelationshipLabel());
map.put("transactionAmountSum2",topTenInflowsList.get(i).getTransactionAmountSum().toString());
map.put("proportion2",proportion);
sumMap.put(i,map);
}
}
}
}
for(int i = 0 ;i<= max;i++){
result.add(sumMap.get(i));
}
return result;
}
具体效果如下:

至此,问题解决。
问题二:

需求是这种表格
刚开始看到很烦恼,因为后面是12个月 不知道该怎么写 有人可能会说直接按照表格那种方式写不行么?答案显然是不行的 因为我不可能去写12个属性,并获取每个属性对应的值。
后来发现我可以循环获取 简单点来说就是 你需要12个key和12个vaule 当然采用集合实体类那种方式显然是行不通的 于是我设置了12个key 循环设置的,vaule肯定也是循环获取的
具体代码如下:
/**
* 3.2.7工资社保统计
* */
public ArrayList<Map<String,String>> wageAndSocialSecurity(String companyId){
ArrayList<Map<String, String>> result = new ArrayList<>();
List<String> year = this.towYearList(companyId); List<String> monthLabel= new ArrayList<>();
for (int i = 1; i <=12 ; i++) {
monthLabel.add("month"+i);
} // 存放月份的集合
List<String> month= new ArrayList<>();
// 设置月份字符串
String tempYear = "";
// 将月份设置成01,02*****10,11,12的形式
for(int a = 0; a < 12; a++) {
if (a < 9) {
tempYear = "0" + (a + 1);
} else {
tempYear = ""+(a+1);
}
// 添加到存放月份的集合中
month.add(tempYear);
}
// 根据年份去遍历
for (int j = 0; j <year.size() ; j++) {
// 创建对象 并设置 companyId和年份
DueDiligenceReport dueDiligenceReport = new DueDiligenceReport();
// companyId
dueDiligenceReport.setCompanyId(companyId);
// 年份
dueDiligenceReport.setYears(year.get(j));
// 工资
List<DueDiligenceReport> wages = dueDiligenceReportDao.wages(dueDiligenceReport);
//社保
List<DueDiligenceReport> socialSecurity = dueDiligenceReportDao.socialSecurity(dueDiligenceReport);
// 判断工资集合是否为空
if (StringUtils.isEmpty(wages)){
// 如果为空 就根据月份的长度创建对象
for (int i = 0; i <month.size() ; i++) {
//创建对象
wages.add(new DueDiligenceReport());
// 将金额设置成0
wages.get(i).setTransactionAmountSum(new BigDecimal(0));
// 设置对应的月份
wages.get(i).setYears(month.get(i));
}
}else {
//定义一个set,因为set集合是有序的
Set<String> mArr = new HashSet<>();
// 将查到的所以月份放到set中
for (DueDiligenceReport w: wages) {
mArr.add(w.getYears());
}
// 循环判断月份
for (int i = 0; i <month.size() ; i++) {
//判断set中的月份 是否包含month集合中的月份
// 不包含就创建对象设置值
if (!mArr.contains(month.get(i))){
//创建对象
wages.add(i,new DueDiligenceReport());
// 将金额设置成0
wages.get(i).setTransactionAmountSum(new BigDecimal(0));
// 设置对应的月份
wages.get(i).setYears(month.get(i));
}
}
}
// 判断社保集合是否为空
if (StringUtils.isEmpty(socialSecurity)){
//如果为空 根据月份的长度 创建对象
for (int i = 0; i <month.size() ; i++) {
//创建对象
socialSecurity.add(new DueDiligenceReport());
// 将金额设置成0
socialSecurity.get(i).setTransactionAmountSum(new BigDecimal(0));
// 设置对应的月份
socialSecurity.get(i).setYears(month.get(i));
}
}else {
//定义一个set集合,因为set集合是有序的
Set<String> mArr = new HashSet<>();
// 将查到的所以月份放到set中
for (DueDiligenceReport w: socialSecurity) {
mArr.add(w.getYears());
}
// 循环判断月份
for (int i = 0; i <month.size() ; i++) {
//判断set中的月份 是否包含month集合中的月份
// 不包含就创建对象设置值
if (!mArr.contains(month.get(i))){
socialSecurity.add(i,new DueDiligenceReport());
socialSecurity.get(i).setTransactionAmountSum(new BigDecimal(0));
socialSecurity.get(i).setYears(month.get(i));
}
}
}
if (wages.size()>0){
Map<String,String> map =new HashMap<>();
map.put("year",year.get(j)+"年");
map.put("type","工资");
for (int i = 0; i < wages.size() ; i++) {
map.put(monthLabel.get(i),wages.get(i).getTransactionAmountSum().toString());
}
result.add(map);
}
if (socialSecurity.size()>0){
Map<String,String> map =new HashMap<>();
map.put("type","社保");
for (int i = 0; i < socialSecurity.size() ; i++) {
map.put(monthLabel.get(i),socialSecurity.get(i).getTransactionAmountSum().toString());
}
result.add(map);
}
}
return result;
}
具体效果如下:

freemarker模板替换生成word的更多相关文章
- 使用freemarker模板引擎生成word文档的开发步骤
1.准备模板文档,如果word文档中有表格,只保留表头和第一行数据:2.定义变量,将word文档中的变量用${var_name}替换:3.生成xml文件,将替换变量符后的word文档另存为xml文件: ...
- windows&lunix下node.js实现模板化生成word文件
最近在做了一个小程序!里面有个功能就是根据用户提交的数据,自动生成一份word文档返回给用户.我也是第一次做这功能,大概思路就是先自己弄一份word模板,后台接受小程序发过来的数据,再根据这些数据将相 ...
- velocity模板技术生成word文档
本文介绍採用velocity技术在Java中生成word文档的方法. 1.新建一个word文档,编辑内容例如以下: 2.将上述word文档另存为htm格式的文件 3.新建一个Java Project项 ...
- python基于word模板批量生成word文件
1.需要用到docxtpl库,用于操作word模板 安装:pip insatll docxtpl 处理之前的word模板 处理后的word 下面直接上代码揭开它的神秘面纱:第一步,读取excel中的内 ...
- poi读写word模板 / java生成word文档
有一word文档表格 形如: 姓名 ${name} 电话 ${tel} 从数据库读取记录替换上述变量 import java.io.FileOutputStream; import java.util ...
- C# 通过word模板动态生成Word
object oMissing = System.Reflection.Missing.Value; Word._Application oWord = new Word.Application(); ...
- [转]java 根据模板文件生成word文档
链接地址:https://blog.csdn.net/ai_0922/article/details/82773466
- FreeMarker生成Word文档
FreeMarker简介: FreeMarker是一款模板引擎:即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具,它不是面向最终用户的,而是一个 ...
- java通过word模板生成word文档
介绍 上次公司项目需要一个生成word文档的功能,有固定的模板根据业务填充数据即可,由于从来没做过,项目也比较着急于是去网上找有没有合适的工具类,找了好几种,看到其中有freeMark模板生成比较靠谱 ...
- PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用Poi实现android中根据模板文件生成Word文档的功能.这里的模板文件是doc文件.如果模板文件是docx文件的话,请阅读 ...
随机推荐
- Java 定时任务技术趋势
简介:定时任务是每个业务常见的需求,比如每分钟扫描超时支付的订单,每小时清理一次数据库历史数据,每天统计前一天的数据并生成报表等等. 作者:黄晓萌(学仁) Java 中自带的解决方案 使用 Time ...
- Nacos 2.0 性能提升十倍,贡献者 80% 以上来自阿里之外
简介: 3 月 20 日,Nacos 2.0 正式发布.Nacos 是阿里巴巴在 2018 年开源的一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台,也可以理解为微服务的注册中心 + 配 ...
- 实时计算 Flink 版总体介绍
简介: 实时计算 Flink 版(Alibaba Cloud Realtime Compute for Apache Flink,Powered by Ververica)是阿里云基于 Apache ...
- [Go] golang 两个数组 list 的合并方式
s := append([]int{1, 2}, []int{3, 4}...) Tool:在线Golang代码运行 Cool:在线 AI 编程助手 https://stackoverflow.com ...
- element-ui表单重置函数 resetFields 无效解决
由element-ui文档中能看到重置表单使用的是如下函数 this.$refs[formName].resetFields(); 但是有时使用它却可能会失效 解决: form-item中要加上pro ...
- 手把手搭建WebSocket多人在线聊天室(SpringBoot+WebSocket)
前言 本文中搭建了一个简易的多人聊天室,使用了WebSocket的基础特性. 源代码来自老外的一篇好文: https://www.callicoder.com/spring-boot-websocke ...
- 02、Linux 排查
Linux 分析排查 1.敏感文件信息 1.1.tmp 目录 /tmp:临时目录文件,每个用户都可以对它进行读写操作.因此一个普通用户可以对 /tmp 目录执行读写操作(ls -alt) 筛查 /tm ...
- 抛砖系列之文本处理工具-awk
AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一.这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德·艾侯.彼得·温伯格和布莱恩·柯林汉姓氏的首个字母 ...
- RocketMQ 事件驱动:云时代的事件驱动有啥不同?
前言: 从初代开源消息队列崛起,到 PC 互联网.移动互联网爆发式发展,再到如今 IoT.云计算.云原生引领了新的技术趋势,消息中间件的发展已经走过了 30 多个年头. 目前,消息中间件在国内许多行业 ...
- python 操作 xlsx
目录 读取/写入:openpyxl demo1 读取/写入:openpyxl demo1 import openpyxl import os # 创建excel def write_excel_xls ...