工具类

     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. 技术解读:Dragonfly 基于 P2P 的智能镜像加速系统 | 龙蜥技术

    简介: 结合 Dragonfly 子项目 Nydus 进行按需加载可以最大限度提升镜像下载速度. 编者按:上世纪末期,基于 C/S 模式的思想,人们发展了 HTTP . FTP 等应用层协议.然而 C ...

  2. Serverless 应用优化四则秘诀

    ​简介:Serverless 架构下,虽然我们更多精力是关注我们的业务代码,但是实际上对于一些配置和成本也是需要进行关注的,并且在必要的时候,还需要根据配置与成本进行对我们的 Serverless 应 ...

  3. [Go] 让 go build 生成的可执行文件对 Mac、linux、Windows 平台一致

    要做到这一点,使用的是交叉编译选项. CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go CGO_ENABLED=0 GOOS=windows ...

  4. [FAQ] Git 修改最后一次的提交人和提交时间 ?

    $ date -R Tue, 21 Mar 2021 21:08:58 +0800 $ git commit --amend  --author="xxx <xxx@email.com ...

  5. SkiaSharp 渲染输出 SVG 文件

    谷歌的 Skia 的一个卖点就是提供了完美的 SVG 的支持,包括输入和输出.输入指的是给一张 SVG 图片,将这个 SVG 渲染出来.输出就是将输出画面保存为 SVG 格式的图片.自然 SkiaSh ...

  6. Sentinel如何持久化数据到Nacos?

    默认情况下 Sentinel 只能接收到 Nacos 推送的消息,但不能将自己控制台修改的信息同步给 Nacos,如下图所示: 但是在生成环境下,我们为了更方便的操作,是需要将 Sentinel 控制 ...

  7. CF1872G

    题意:一个正整数序列,\(a[i] < 10^9\),求 \(l\),\(r\),最大化 \[\sum_{i = 1}^{l - 1} a[i] + \prod_{i = l}^r a[i] + ...

  8. 累计预扣法个税,怎么算?(附excel)

    累计预扣法个税计算 依法纳税是每个公民的义务,但看着每个月递增的个税,你可能会发出疑问,这到底是怎么算的?这就要引出2019年1月1日实施新实施的个税法,累计预扣法.即自2019年1月1日起,居民个人 ...

  9. c#胖东来小程序自动购物程序(接单,windows桌面程序、linux程序、网络应用等等)

    一.程序效果 自动打开胖东来小程序,自动购物 二.实现 先截屏,然后利用opencv库识别下一步按键所在位置,然后使用mouse_event控制鼠标,模拟人的动作 第一步,截取屏幕 static Bi ...

  10. 【爬虫案例】用Python爬取抖音热榜数据!

    目录 一.爬取目标 二.编写爬虫代码 三.同步讲解视频 3.1 代码演示视频 四.获取完整源码 一.爬取目标 您好,我是@马哥python说,一名10年程序猿. 本次爬取的目标是:抖音热榜 共爬取到5 ...