工具类
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; }
具体效果如下: