POI 导出excel ,xlsx 公式多个下拉框 XSSF

1 篇文章 0 订阅

业务需求需要导出Excel,然而xls部分公式无法使用,且导出效率和行数有限制,因此更换导出文件为xlsx,下拉框个数根据参数传入。代码写得有点乱,如下代码为导出excel xlsx格式的代码

/**
*导出Excel  xlsx
* @param excelHeader 导出excel的头部 格式UserNo#userNo(输出excel的列的首行名字#所在列对应的实体bean的属性名字),多列以','隔开  参考UserController里面的导出用户功能;
* @param dataList    需要导出数据的集合。
* @param indexs 下拉框索引
* @param slist 下拉框数组,支持多个下拉框
*/
public static <T> HSSFWorkbook downloadExcel(HttpServletResponse response, String fileName, String excelHeader, Integer[] indexs, List<String[]> slist) throws Exception {
    String[] excelHeaderArray = null;
    if (excelHeader != null) {
        excelHeaderArray = excelHeader.split(",");
    }
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
    XSSFWorkbook wb = new XSSFWorkbook();
    XSSFCellStyle styleb = wb.createCellStyle();
    styleb.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
    XSSFSheet data = wb.createSheet("Sheet1");
    XSSFSheet select = wb.createSheet("select");
    wb.setSheetHidden(1, true);
    Row rowFirst = data.createRow(0);//第一个sheet的第一行为标题
    for (int i = 0; i < excelHeaderArray.length; i++) {
        Cell cell = rowFirst.createCell(i); //获取第一行的每个单元格
        XSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
        //标头字体样式
        Font fontStyle = wb.createFont();
        fontStyle.setFontName(Const.EXPORT_EXCEL_HEADER_FONT);
        fontStyle.setFontHeightInPoints(Const.EXPORT_EXCEL_HEADER_FONT_SIZE);
        fontStyle.setBoldweight(Font.BOLDWEIGHT_BOLD);
        style.setFont(fontStyle);
        String excelHeaderstr = excelHeaderArray[i];
        if (StringUtils.isNotEmpty(excelHeaderstr) && excelHeaderstr.contains("*")) {
            fontStyle.setColor(Font.COLOR_RED);
        } else {
            //fontStyle.setColor(Font.COLOR_NORMAL);
        }

        data.setColumnWidth(i, excelHeaderArray[i].length() * 2 * 256); //设置每列的列宽
        cell.setCellStyle(style); //加样式
        cell.setCellValue(excelHeaderArray[i]); //往单元格里写数据
        cell.setCellType(Cell.CELL_TYPE_STRING);
    }

    //设置单元格的字体
    XSSFCellStyle style2 = wb.createCellStyle();
    XSSFDataFormat format = wb.createDataFormat();
    style2.setDataFormat(format.getFormat("@"));
    style2.setBorderBottom(XSSFCellStyle.BORDER_THIN);
    style2.setBorderTop(XSSFCellStyle.BORDER_THIN);
    style2.setBorderLeft(XSSFCellStyle.BORDER_THIN);
    style2.setBorderRight(XSSFCellStyle.BORDER_THIN);
    style2.setAlignment(XSSFCellStyle.ALIGN_CENTER);
    style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
    Font dataFont = wb.createFont();
    dataFont.setFontHeightInPoints(Const.EXPORT_EXCEL_BODY_FONT_SIZE);
    dataFont.setFontName(Const.EXPORT_EXCEL_BODY_FONT);
    style2.setFont(dataFont);

    //默认创建100行数据
    for (int i = 1; i < 100; i++) {
        Row row = data.createRow(i);

        for (int j = 0; j < excelHeaderArray.length; j++) {
            Cell cell = row.createCell(j); //获取第一行的每个单元格
            cell.setCellType(Cell.CELL_TYPE_STRING);
            cell.setCellStyle(style2);
        }
    }
    //列 默认只支持26列,需要增加在数组中增加
    String[] arr = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
    int index = 0;
    Row row = null;
    //循环输出slist  下拉框数组集合。
    for (int i = 0; i < slist.size(); i++) {
        String[] selectData = slist.get(i);
        if (selectData == null) {
            selectData = new String[0];
        }
        下拉框的索引位置
        int rowNum = indexs[i];
        //下拉框公式
        String strFormula = "'select'!$" + arr[index] + "$2:$" + arr[index] + "$" + (selectData.length + 1); //select第A1到A5000作为下拉列表来源数据
        select.setColumnWidth(i, 4000); //设置每列的列宽
        //设置下拉框数据校验
        data.addValidationData(ExcelUtil.setXSSFDataValidation(select, strFormula, 1, 50000, rowNum, rowNum)); 
//下拉列表元素很多的情况,循环下入到隐藏的sheet中
        for (int j = 0; j < selectData.length; j++) {
            if (index == 0) {
                row = select.createRow(j + 1); //创建数据行
                select.setColumnWidth(j + 1, 4000); //设置每列的列宽
                row.createCell(0).setCellValue(selectData[j]); //设置对应单元格的值

            } else {
                int rowCount = select.getLastRowNum();
                //判断最后一行数据的索引是否大于当前的行数,大于则需要创建一行,小于只需要创建单元格,赋值就好了。
                if (j < rowCount) {
                    select.getRow(j + 1).createCell(index).setCellValue(selectData[j]); //设置对应单元格的值
                } else {
                    select.setColumnWidth(j + 1, 4000); //设置每列的列宽
                    //创建行、创建列
                    select.createRow(j + 1).createCell(index).setCellValue(selectData[j]); //设置对应单元格的值
                }
            }
        }
        index++;
    }
    try {
        OutputStream outputStream = response.getOutputStream();// 打开流
        wb.write(outputStream);// HSSFWorkbook写入流
        //wb.close();// HSSFWorkbook关闭
        outputStream.flush();// 刷新流
        outputStream.close();// 关闭流
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

 

 

ExcelUtil:setXSSFDataValidation

public static DataValidation setXSSFDataValidation(XSSFSheet sheet,String formula,
                                          int firstRow, int endRow, int firstCol, int endCol){
   CellRangeAddressList addressList = new CellRangeAddressList(
         firstRow, endRow, firstCol, endCol);
   DataValidationHelper dvHelper = sheet.getDataValidationHelper();
   XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
         dvHelper.createFormulaListConstraint(formula);
   XSSFDataValidation validation =(XSSFDataValidation)dvHelper.createValidation(
         dvConstraint, addressList);
   //sheet.addValidationData(validation);
   return validation;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值