java 生成 模板文件 excel,word

1 篇文章 0 订阅
1 篇文章 0 订阅

生成excel

两种方式:1.模板文件为.xls或.xlsx  2.模板文件.ftl

当然两种生成文件的方式都有各自的优点与缺点 以及技术上的不同。个人意见。本人亲自做了两种例子。

1.模板文件为.xls(.xlsx),我用的是org.apache.poi的包。优点就是:通俗易懂,生成的文件格式不会乱,不会出险兼容性问题(只要模板在原机器上能正常打开)。缺点就是:赋值麻烦,需要非常仔细。行与列要完全和数据的逻辑一一对应。

2.模板文件为.ftl ,当然对这个后缀名熟悉的小伙伴一看就知道用了 freemark引擎模板技术。优点:赋值简单,咱做java的对${}肯定很熟悉,没错,就是以这种方式赋值。 只要咱们在excel模板中提前定义号变量就OK。缺点:貌似有点多😫,1)生成ftl文件复杂,这里就不多做介绍;2)兼容性不太好;3)稍不注意生成的excel的格式可能就不是你想要的。

所以我推荐用poi技术来实现。说的有点多,上代码。

大家来简单看一下我的模板。

对没错,就是很多个sheet页,我需要向每个sheet页赋值。

第二个sheet页没有列表,第三个sheet页,甚至后面的20多个sheet页都是列表。

看代码。

/**
     * 生成excel
     * @param data   数据
     * @param templateName   模板文件名称(huzhu.xlsx)
     * @param generateFilePath  生成文件的路径(F:\generate\report\cwt1051577170794002\report)
     * @param generateFileName  生成文件的名称(new99案(测试上海乐凡).xlsx)
     * @param sourcePath        模板文件的源路径  (F:\templete)
     * @return
     */
    public static File generateReportPoi(TemplateHelpData data, String templateName, String generateFilePath, String generateFileName, String sourcePath){
        try {
            FileInputStream template = new FileInputStream(new File(sourcePath + File.separator + templateName));
            File generateFile = new File(generateFilePath + File.separator + generateFileName + ".xlsx");
            if (!generateFile.getParentFile().exists()){
                generateFile.getParentFile().mkdirs();
            }
            FileOutputStream dataFile = new FileOutputStream(generateFile);
            XSSFWorkbook templateWorkBook = new XSSFWorkbook(template);
            XSSFWorkbook workbook = new XSSFWorkbook();
            workbook = templateWorkBook;

            //sheet0  sheet页 从0开始
            //赋值数据  sheet1
            XSSFSheet sheet1 = workbook.getSheetAt(1);
            String cellValue1 = data.getHelpData2().getCellValue1();
            String [] names = cellValue1.split(",");
            for (int i = 0; i < names.length; i++) {
                setCellValue(sheet1,1,i + 3,names[i]);
            }
//            setCellValue(sheet1,1,3,data.getHelpData2().getCellValue1());
            setCellValue(sheet1,2,3,data.getHelpData2().getCellValue2());

            Row rowD = sheet1.getRow(3 - 1);
            Cell cellD = rowD.getCell(3 - 1);
            cellD.setCellValue(new SimpleDateFormat("yyyy-MM-dd").parse(data.getHelpData2().getCellValue3()));

            if (!StringUtils.isEmpty(data.getHelpData2().getCellValue4())){
                Row rowDD = sheet1.getRow(4 - 1);
                Cell cellDD = rowDD.getCell(3 - 1);
                cellDD.setCellValue(new SimpleDateFormat("yyyy-MM-dd").parse(data.getHelpData2().getCellValue4()));
            }

//            setCellValue(sheet1,3,3,data.getHelpData2().getCellValue3());
//            setCellValue(sheet1,4,3,data.getHelpData2().getCellValue4());

            setCellValue(sheet1,5,3,data.getHelpData2().getCellValue5());
            setCellValue(sheet1,6,3,data.getHelpData2().getCellValue6());
            setCellValue(sheet1,7,3,data.getHelpData2().getCellValue7());
            setCellValue(sheet1,8,3,data.getHelpData2().getCellValue8());
            setCellValue(sheet1,9,3,data.getHelpData2().getCellValue9());
            setCellValue(sheet1,10,3,data.getHelpData2().getCellValue10());
            setCellValue(sheet1,11,3,data.getHelpData2().getCellValue11());

            //后面21个sheet页   从 k + 1 个 sheet 页开始循环赋值
            for (int k = 1; k < 22; k++) {
                int index = 0;
                List<HelpDirectionLine> dataSheet = data.getHelpDataLists().getSheetValue(k);
                XSSFSheet sheet =  workbook.getSheetAt(k + 1);
                int line = 2;
                for (HelpDirectionLine helpDirectionLine : dataSheet) {
                    int lastCell = sheet.getRow(0).getPhysicalNumberOfCells();//获取每个sheet页的列数
                    XSSFRow row = sheet.createRow(line ++);//都从第二行开始增加
                    if (k  == 5){//无索引列
                        XSSFCell cell = null;
                        for (int i = 1; i < lastCell + 1; i++) {
                            cell = row.createCell(i - 1,Cell.CELL_TYPE_STRING);
                            cell.setCellValue(helpDirectionLine.getColValue(i));//没有索引列 从第一列开始取值
                        }
                    }else{
                        for (int i = 0; i < lastCell; i++) {
                            XSSFCell cell = null;
                            if (i == 0){//索引列
                                cell = row.createCell(0,Cell.CELL_TYPE_NUMERIC);
                                cell.setCellValue(++index);
                            }else{
                                cell = row.createCell(i,Cell.CELL_TYPE_STRING);
                                cell.setCellValue(helpDirectionLine.getColValue(i));
                            }
                        }
                    }
                }
            }
            workbook.write(dataFile);
            return generateFile;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
/**
     * 给单元格赋值
     * @param sheet
     * @param i 行 从1开始
     * @param j 列 从1开始
     * @param value
     */
    private static void setCellValue(Sheet sheet,int i,int j,String value){
        Row row = sheet.getRow(i - 1);
        Cell cell = row.getCell(j - 1);
        cell.setCellValue(value);
    }

其实代码一看就明白,就是获取每个sheet页,然后向第i行,第j列赋值。

简单介绍写第二种实现方式:

生成.ftl文件, 就是将制作好的exel文件,另存为xml,然后格式化xml,把需要删除的删除。一下是我制作的excel模板

代码:

/**
     * 根据模板 生成Excel 报告
     * @param data
     * @param templateName  模板名称
     * @param generateFilePath 生成文件路径
     * @param generateFileName 生成文件名称
     * @param sourcePath  原始模板路径
     * @return
     */
    public static File  generateReport(TemplateHelpData data, String templateName, String generateFilePath, String generateFileName, String sourcePath){
        Map<String,Object> map =  new HashMap<String,Object>();
        map.put("surveyCompletion",data.getHelpData1().getSurveyCompletion());
        map.put("cellValue1",data.getHelpData2().getCellValue1());
        map.put("cellValue2",data.getHelpData2().getCellValue2());
        map.put("cellValue3",data.getHelpData2().getCellValue3());
        map.put("cellValue4",data.getHelpData2().getCellValue4());
        map.put("cellValue5",data.getHelpData2().getCellValue5());
        map.put("cellValue6",data.getHelpData2().getCellValue6());
        map.put("cellValue7",data.getHelpData2().getCellValue7());
        map.put("cellValue8",data.getHelpData2().getCellValue8());
        map.put("cellValue9",data.getHelpData2().getCellValue9());
        map.put("cellValue10",data.getHelpData2().getCellValue10());
        map.put("cellValue11",data.getHelpData2().getCellValue11());
        map.put("data1",data.getHelpDataLists().getDirections1());
        map.put("data2",data.getHelpDataLists().getDirections2());
        map.put("data3",data.getHelpDataLists().getDirections3());
        map.put("data4",data.getHelpDataLists().getDirections4());
        map.put("data5",data.getHelpDataLists().getDirections5());
        map.put("data6",data.getHelpDataLists().getDirections6());
        map.put("data7",data.getHelpDataLists().getDirections7());
        map.put("data8",data.getHelpDataLists().getDirections8());
        map.put("data9",data.getHelpDataLists().getDirections9());
        map.put("data10",data.getHelpDataLists().getDirections10());
        map.put("data11",data.getHelpDataLists().getDirections11());
        map.put("data12",data.getHelpDataLists().getDirections12());
        map.put("data13",data.getHelpDataLists().getDirections13());
        map.put("data14",data.getHelpDataLists().getDirections14());
        map.put("data15",data.getHelpDataLists().getDirections15());
        map.put("data16",data.getHelpDataLists().getDirections16());
        map.put("data17",data.getHelpDataLists().getDirections17());
        map.put("data18",data.getHelpDataLists().getDirections18());
        map.put("data19",data.getHelpDataLists().getDirections19());
        map.put("data20",data.getHelpDataLists().getDirections20());
        map.put("data21",data.getHelpDataLists().getDirections21());
        //所有key 的value 不能为空 此处做转换
        Iterator<String> iterator = map.keySet().iterator();
        while (iterator.hasNext()){
            String key = iterator.next();
            Object value = map.get(key);
            if (value == null) {
                map.put(key,"");
            }else{
                String replacement = "&#10;";//换行
                if (value instanceof String){
                    String tempValue = value.toString();
                    tempValue = tempValue.replaceAll("<","&lt;");
                    tempValue = tempValue.replaceAll(">","&gt;");
                    tempValue = tempValue.replaceAll("\n",replacement);
                    map.put(key,tempValue);
                } else if(value instanceof List){
                    List<HelpDirectionLine> lines = (List<HelpDirectionLine>)value;
                    for (HelpDirectionLine line : lines) {
                        Field[] fields = HelpDirectionLine.class.getDeclaredFields();
                        for (Field field : fields) {
                            field.setAccessible(true);
                            try {
                                Object object = field.get(line);
                                if (object == null){
                                    field.set(line,"");
                                }
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }

                        }
                    }
                }else {
                    map.put(key,value);
                }
            }
        }
        File file = createExcel(map,templateName,generateFilePath,generateFileName,sourcePath);
        return file;
    }

    private static File createExcel(Map dataMap,String templateName,String filePath,String fileName,String sourcePath){
        try {
            //创建配置实例
            Configuration configuration = new Configuration();

            //设置编码
            configuration.setDefaultEncoding("UTF-8");

            //ftl模板文件统一放至 com.lun.template 包下面
//            configuration.setClassForTemplateLoading(WordUtil.class,sourcePath);
            configuration.setDirectoryForTemplateLoading(new File(sourcePath));

            //获取模板
            Template template = configuration.getTemplate(templateName);

            //输出文件
            File outFile = new File(filePath+File.separator + fileName + ".xlsx");

            //如果输出目标文件夹不存在,则创建
            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();
            return outFile;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

 

最后生成的文件:

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值