工具类

     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. 疫情带火了这款APP:2600个学生一天点赞70万次

      这几天,全国中小学生经历了"过山车"一样的心情. 因为疫情的不断蔓延,1月27日,教育部下发通知,2020年春季学期延期开学. 随后,教育部又提出"利用网络平台,停课 ...

  2. 平安保险基于 SPI 机制的 RocketMQ 定制化应用

    ​简介:本文讲讲述平安保险为何选择 RocketMQ,以及在确定使用消息中间件后,又是如何去选择哪款消息中间件的. 作者:孙园园|平安人寿资深开发 为什么选用 RocketMQ 首先跟大家聊聊我们为什 ...

  3. DevOps 能力提升模型

    简介: DevOps 能力反映的是技术研发响应业务变化的能力.随着组织规模的增加和业务复杂性增长,DevOps 能力会变得越来越重要.持续提升 DevOps 的能力成为技术研发的共同挑战. 编者按:本 ...

  4. WPF 解决 ObservableCollection 提示 Cannot change ObservableCollection during a CollectionChanged event 异常

    本文告诉大家在使用 ObservableCollection 时,抛出 InvalidOperationException 异常,提示 Cannot change ObservableCollecti ...

  5. WPF 自己封装 Skia 差量绘制控件

    使用 Skia 能做到在多个不同的平台使用相同的一套 API 绘制出相同界面效果的图片,可以将图片绘制到应用程序的渲染显示里面.在 WPF 中最稳的方法就是通过 WriteableBitmap 作为承 ...

  6. 优秀的 Modbus 主站(主机、客户端)仿真器、串口调试工具

    目录 优秀的 Modbus 主站(主机.客户端)仿真器.串口调试工具 主要功能 软件截图 优秀的 Modbus 主站(主机.客户端)仿真器.串口调试工具 modbus master,modbus,串口 ...

  7. 通过Google浏览器Cookie文件获取cookie信息,80以上版本有效

    public class ReadCookie { /// <summary> /// </summary> /// <param name="hostName ...

  8. 深入浅出玩转fPGA-读书笔记

    笔记1 关于异步复位同步释放的理解 先看代码: 其中有两个always语句,把2个触发器叠加,当按下复位信号rst_n是,两个触发器都复位(清零).当rst_n释放时,重点就来了,rst_n释放的时刻 ...

  9. JS制作日历小事件和数码时钟--JavaScript实例集锦(初学)

    运用JS的innerHTML,和for循环实现日历小部件内容和日期的转换. <!DOCTYPE html> <html> <head> <title>日 ...

  10. 扩展实现Unity协程的完整栈跟踪

    现如今Unity中的协程(Coroutine)方案已显得老旧,Unitask等异步方案可以做到异常捕获等yield关键字处理起来很麻烦的问题, 并且Unity官方也在开发一套异步方案,但对于临时加入到 ...