JAVA _POI_EXCEL万能公式,满足百分之九十的导出,模板自定义,代码无需动

  • Post author:
  • Post category:java


做项目的时候,经常会有一些报表类的应用,需要导出,但是POI提供了大量的API,写一个复杂的导出文件,光对样式,格式就需要几百行的代码,不仅不美观,可读性也很差,对此,我做了不少研究后,发现通过事先设计好EXCEL的模板,java只做对数据的解析,将数据填进模板里,可读性强,代码量少,对于某些情景能做到万能公式的效果,无需修改代码,修改模板即可完成复杂的导出文件。废话不多说,代码献上。

首先是工具类:

public class ExcelUtil {
    public ExcelUtil() {
    }
    public static Workbook setDataInTemplateExcel(Workbook wb, int rowNum, int colNum, int sheetNum, List<Map<String, Object>> data, boolean isProtect) {
//数据写在第几个sheet页中
        Sheet sheet = wb.getSheetAt(sheetNum);
//从第几行开始写入
        int i = rowNum;

        for(Iterator var8 = data.iterator(); var8.hasNext(); ++i) {
            Map<String, Object> mapStore = (Map)var8.next();
            Row row = sheet.getRow(i);
            if (row == null) {
                row = sheet.createRow(i);
            }
//从第几列写入
            int j = colNum;

            for(Iterator var12 = mapStore.entrySet().iterator(); var12.hasNext(); ++j) {
                Entry<String, Object> entry = (Entry)var12.next();
                Cell cell = row.getCell(j);
                if (cell == null) {
                    cell = row.createCell(j);
                }

                if (entry.getValue() != null) {
//这里根据你的业务需要,如还有日期,等其他形式 也可以继续添加
                    Object val = entry.getValue();
                    if (!(val instanceof Long) && !(val instanceof Integer)) {
                        if (val instanceof Double) {
                            cell.setCellValue(Double.parseDouble(val.toString()));
                        } else {
                            cell.setCellValue(val.toString());
                        }
                    } else {
                        cell.setCellValue((double)Long.parseLong(val.toString()));
                    }
                } else {
                    cell.setCellValue("");
                }
            }
        }
//文件加密,加密后不允许他们编辑
        if (isProtect) {
            sheet.protectSheet("123");
        }

        return wb;
    }
}

业务逻辑代码:

@RequestMapping(value = "/export",method = {RequestMethod.GET})
public void export(HttpServletResponse response) throws Exception{
    //输出流
    ServletOutputStream out = response.getOutputStream();
    String exportPath="test";
    //设置表名
    setResponseHeader(response,"测试表格");
    // 1. 加载模板文件
    String fileDir = System.getProperty("user.dir") + File.separator
            + "template" + File.separator;
    String filePath = fileDir + exportPath + ".xlsx";

    File file = new File(filePath);
    //判断模板是否存在
    if (!file.exists()) {
       throw new Exception("模板不存在");
    }
    //数据源  用于测试 本人造了几个数据
    List<Map<String, Object>> dateList=new ArrayList<>();
    for (int i=0;i<10;i++) {
        Map<String, Object> map = new LinkedHashMap<>();
        map.put(i+"e",i+1);
        map.put(i+"a",i+2);
        dateList.add(map);
    }
    InputStream stream = null;
    stream =new FileInputStream(file);
    Workbook wb = WorkbookFactory.create(stream);
    //参数一次代表:wb 输入流 rowNum 第几行 colNum 第几列 sheetNum 第几个sheet页 datelist 数据源 isProtect Excel文件是否可被被人编辑
    //下面的参数表示从第3行第1列第一个sheet页开始写入,不对excel加密
    wb = ExcelUtil.setDataInTemplateExcel(wb, 2, 0, 0,dateList,false);

    wb.write(out);
    stream.close();

    out.close();

}

//文件名
public  HttpServletResponse setResponseHeader(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
    response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName+".xlsx").getBytes("utf-8"), "ISO-8859-1"));
    return response;
}

两段代码即可

文件模板可根据自己的业务存放:

模板样式:

导出结果显示:

短短几行代码搞定 是不是很简单呢



版权声明:本文为yousiwangqh原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。