工具类

     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的更多相关文章

  1. 使用freemarker模板引擎生成word文档的开发步骤

    1.准备模板文档,如果word文档中有表格,只保留表头和第一行数据:2.定义变量,将word文档中的变量用${var_name}替换:3.生成xml文件,将替换变量符后的word文档另存为xml文件: ...

  2. windows&lunix下node.js实现模板化生成word文件

    最近在做了一个小程序!里面有个功能就是根据用户提交的数据,自动生成一份word文档返回给用户.我也是第一次做这功能,大概思路就是先自己弄一份word模板,后台接受小程序发过来的数据,再根据这些数据将相 ...

  3. velocity模板技术生成word文档

    本文介绍採用velocity技术在Java中生成word文档的方法. 1.新建一个word文档,编辑内容例如以下: 2.将上述word文档另存为htm格式的文件 3.新建一个Java Project项 ...

  4. python基于word模板批量生成word文件

    1.需要用到docxtpl库,用于操作word模板 安装:pip insatll docxtpl 处理之前的word模板 处理后的word 下面直接上代码揭开它的神秘面纱:第一步,读取excel中的内 ...

  5. poi读写word模板 / java生成word文档

    有一word文档表格 形如: 姓名 ${name} 电话 ${tel} 从数据库读取记录替换上述变量 import java.io.FileOutputStream; import java.util ...

  6. C# 通过word模板动态生成Word

    object oMissing = System.Reflection.Missing.Value; Word._Application oWord = new Word.Application(); ...

  7. [转]java 根据模板文件生成word文档

    链接地址:https://blog.csdn.net/ai_0922/article/details/82773466

  8. FreeMarker生成Word文档

    FreeMarker简介: FreeMarker是一款模板引擎:即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具,它不是面向最终用户的,而是一个 ...

  9. java通过word模板生成word文档

    介绍 上次公司项目需要一个生成word文档的功能,有固定的模板根据业务填充数据即可,由于从来没做过,项目也比较着急于是去网上找有没有合适的工具类,找了好几种,看到其中有freeMark模板生成比较靠谱 ...

  10. PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用Poi实现android中根据模板文件生成Word文档的功能.这里的模板文件是doc文件.如果模板文件是docx文件的话,请阅读 ...

随机推荐

  1. EasyCV带你复现更好更快的自监督算法-FastConvMAE

    简介: 近期FastConvMAE工作在EasyCV框架内首次对外开源,本文将重点介绍ConvMAE和FastConvMAE的主要工作,以及对应的代码实现,最后提供详细的教程示例如何进行FastCon ...

  2. Apsara Stack 技术百科 | 数字化业务系统安全工程

    ​简介:数字化平台已经与我们生活紧密结合,其用户规模庞大,一旦系统出现故障,势必会造成一定生活的不便.比如疫情时代,健康码已经成为人们出门必备的条件,一旦提供健康码服务平台出现故障,出行将变得寸步难行 ...

  3. 性能提升40%!阿里云神龙大数据加速引擎获TPCx-BB世界排名第一

    ​简介:神龙大数据加速引擎,针对大数据常用组件,如Spark.Hadoop.Alluxio等,结合阿里云神龙架构的特性,进行软硬一体化优化,形成独一无二的性能优势,最终,使复杂SQL查询场景性能相比社 ...

  4. 非技术 对以后各大应用功能与 AI 助手的思考

    本文记录我对于 AI 助手在未来给各大应用或网站或设备带来的影响的思考 结论:未来的各大应用或网站或者是设备,都不会出现满屏的眼花缭乱的功能,取代的是各自有一个专属的 AI 助手,通过 AI 助手与人 ...

  5. MSSQL—存储过程分页

    SET QUOTED_IDENTIFIER ON SET ANSI_NULLS ON GO CREATE PROCEDURE [dbo].[GetPagingStr] @PRESQL VARCHAR( ...

  6. Solution Set - 数论相关

    绝了,六道题都差一步想出来或者差一个细节就开始看题解. CF906D Link&Submission. 要求 \(a^b\bmod p\),那就要求 \(b\bmod \varphi(p)\) ...

  7. 简说python之批量操作主机

    目录 Python批量操作主机 安装paramiko模块 远程ssh控制主机 目前,很多的工作都是批量的操作Linux主机.通过python脚本,封装Linux的shell命令.保证批量操作,简易优化 ...

  8. Aliplayer通过HLS流式播放Aliyun Mps(媒体处理)转码的加密视频

    前言 公司需求,上传的视频需要加上公司Logo,同时播放需要采用流式播放禁止下载. 现有的环境在阿里云上,所以自然想到了阿里云的产品[媒体处理]的转码功能. 转码配置 配置比较简单,采用阿里云HLS标 ...

  9. Java 中的深拷贝和浅拷贝你了解吗?

    前言 Java 开发中,对象拷贝是常有的事,很多人可能搞不清到底是拷贝了引用还是拷贝了对象.本文将详细介绍相关知识,让你充分理解 Java 拷贝. 一.对象是如何存储的? 方法执行过程中,方法体中的数 ...

  10. gitlab docker 自动部署报错 /bin/bash: line 118: docker: command not found

    原因找不到docker,我们需要绑一下docker 列出所有gitlab-runner配置文件 find / | grep config.toml [root@izwz99pke7zxkpm7l51t ...