企业级开发使用POI踩坑盘点

281 阅读3分钟
  • 持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

  • 毕业刚好两年整,2020.06-2022.06 哈哈刚好就是疫情那边毕业的。说实话毕业那年找工作是真的难。好多小企业都因为疫情倒闭了!算了过去的事情就不说了

代码涉及机密 我就不给大家写全了 更具自己的业务场景不同。借鉴一下方法的使用哈!

今天主要围绕POI这个框架来说

首先excel也就相当于我们的数据库查不来的表数据。表头对应的字段属性。下面的数据对应的数据库中的每一条记录。

基本用法我就不说了!就说一下在企业级开发过程中,我们会遇到的各种各样的 情况。总结问题:

poi设置自适应列宽的三种方法

sheet.autoSizeColumn(i); (版本不能太老)
sheet.autoSizeColumn(i, true);(合并的单元格使用)
sheet.setColumnWidth(i, “列名”.getBytes().length*2*256);(中文适用)

POi报错2:For input string: "null"

这个问题一般都是导出报错,怎么解决?

  • 导出流程:在导出前先去查数据库里面的数据、在把数据写每一个单元格中。
if (CommUtil.notEquals("null", entry.getValue().toString())) {
                        cell.setCellValue(Double.valueOf(entry.getValue().toString()));
                    } else {
                        cell.setCellValue(0);
                    }

以此类推 。您去判断就行···· 比较粗暴

POi框架 导入时单元格中是:科学计数(4.8e9)

        String content; 
        {  // 数值类型:
  // 修复科学计数问题
NumberFormat numberFormat = NumberFormat.getInstance();
content = numberFormat.format(cell.getNumericCellValue());
 if (content.indexOf(",") >= 0) {
 content = content.replace(",", "");
   }
 log.debug("handleRow: cell.getNumericCellValue(){}:{}",i,content);
            }

将单元格内容居中文本类型

    /**
     *  单元格内容居中 文本类型
     * @param wb
     * @return
     */
    private XSSFCellStyle setStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        XSSFDataFormat dataFormat = wb.createDataFormat();
        //文本类型
        cellStyle.setDataFormat(dataFormat.getFormat("@"));
        //左右居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        return cellStyle;
    }

将单元设置成:数值类型(做报表时:比较重要)

    /**
     *  数值类型
     * @param wb
     * @return
     */
    private XSSFCellStyle setStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
         cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00"));
        return cellStyle;
    }

给大家说一个秘密

  • 先设置单元格格式-在设置单元格类型哈!如果反了 ,他就不会生效 哈哈哈 ** 注意哈**
            // 改成数值型
            cell.setCellStyle(hssfCellStyleDouble);
            // 把公式塞入合计列
            cell.setCellFormula(sumString);

怎么单元格中写 excel 的函数

这里举个例子 合计求和

        String colString;//长度转成ABC后的列
    
        String sumString;//求和公式
        // 合计
        int totalColumn = 0;
        //获得总列数
        int cells = sheet.getRow(0).getPhysicalNumberOfCells();
        //获得总行数
        int rowNum=sheet.getLastRowNum();
        // 得到总计那一行
        XSSFRow xssfRow = sheet.createRow(1);
        XSSFCell cell = xssfRow.createCell(0);
        cell.setCellValue("合计:");
        // 遍历每一列
        for (int i = totalColumn, size = cells; i < size; i++) {
            cell = xssfRow.createCell(i);
            //长度转成ABC列
            colString = CellReference.convertNumToColString(i);
            if (rowNum == 2) {
                sumString = "SUM(" + colString + "3"+")";
            } else {
                //求和公式 求 2 至 总行数 单元格的总和
                sumString = "SUM(" + colString + "3:" + colString + rowNum+1 + ")";
            }
            // 改成数值型
            cell.setCellStyle(hssfCellStyleDouble);
            // 把公式塞入合计列
            cell.setCellFormula(sumString);
            totalColumn++;
        }

单元格设置下拉

/**
     * 设置下拉框
     * @param sheet    指定sheet页
     * @param values   下拉框的值
     * @param firstRow 起始行号
     * @param lastRow  终止行号
     * @param firstCol 起始列号
     * @param lastCol  终止列号
     */
    public static void setDropDownBox(XSSFSheet sheet, String[] values, Integer firstRow, Integer lastRow,
            Integer firstCol, Integer lastCol) {
        XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
        XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createExplicitListConstraint(
                values);
        CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
        DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);
        //这两行设置单元格只能是列表中的内容,否则报错
        validation.setSuppressDropDownArrow(true);
        validation.setShowErrorBox(true);
        sheet.addValidationData(validation);
    }

导入导出的接口 尽量都用void哈

后面还遇到bug 我会接着往下补充并 告诉大家解决方法

可以其实可以通过反射加注解来实现对数据导入导出。等以后有时间给大家 出一版