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;
    }

具体效果如下:

原文地址:https://www.cnblogs.com/lemperor/p/15347515.html