Java POI 爬坑笔记

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

做ERP的经常要面对数据来源的问题。最头痛的是跨公司,部门,系统的数据交流。
通过实践,我们发现EXCEL是比较合适的格式。相对于XML,JSON,可读性和操作自由度都比较理想。

通常我们用JAVA+POI处理。
首先说一下POI的限制。
1,不能处理太大的数据,文档大小最好在1M以下,行数小于1w;
因为太过“自由”,为了保证可靠性,通常需要对数据预处理,导致效率低下,超过1M的数据可能造成假死。
2,空格,大小写,非法字符,数据格式等等都会造成bug,各种读数据预处理是必须的。
以下列出我常用的几个方法

    /**
     * @description 处理可能是数字,输出带小数点的情况,全部转成字符(去除所有空格)
     */
    public static String getNoSpaceString(Cell cell) {
        if (null == cell)
            return null;
        switch (cell.getCellTypeEnum()) {// 判断格式
        case NUMERIC:// 数字,double转数字
            return (new BigDecimal(cell.getNumericCellValue())).toString();
        case STRING:
            return removeSpacing(cell.getStringCellValue());
        case FORMULA:// 带公式计算
            try {
                // 是字符
                return removeSpacing(cell.getRichStringCellValue().toString());
            } catch (Exception e) {
                // 是数字
                String s2 = String.valueOf(cell.getNumericCellValue());
                return s2;
            }
        default:
            return cell.toString();
        }
    }

    // 去除所有空格
    private static String removeSpacing(String input) {
        final Pattern p = Pattern.compile("\\s+");
        Matcher m = p.matcher(input);
        return m.replaceAll("");
    }

    public static float getFloat(Cell cell) {
        if (null == cell)
            return 0;
        switch (cell.getCellTypeEnum()) {// 判断格式
        case NUMERIC:// 数字,double转数字
            return (float) (cell.getNumericCellValue());
        case STRING:
            float f;
            try {
                // 是字符
                String s = cell.getStringCellValue();
                s = s.replaceAll("[^\\d\\.]", "");
                f = Float.parseFloat(s);
            } catch (NumberFormatException e) {// 是字符,但是不能转成数字
                return 0;
            }
            return f;
        case FORMULA:// 带公式计算
            try {
                float f2 = Float.parseFloat(cell.getStringCellValue());
                return f2;
            } catch (NumberFormatException e) {// 是字符,但是不能转成数字
                return 0;
            } catch (Exception e) {
                // 是数字
                return (float) (cell.getNumericCellValue());
            }
        default:
            return 0;
        }
    }

    //日期
    public static String getDateString(Cell cell) {
        if (cell == null)
            return null;
        switch (cell.getCellTypeEnum()) {// 判断格式
        case STRING:
            return cell.getStringCellValue();
        case BOOLEAN:
            return String.valueOf(cell.getBooleanCellValue());
        case FORMULA:// 带公式计算
            try {
                // 是字符
                return cell.getRichStringCellValue().toString();
            } catch (Exception e) {
                // 是数字
                String s2 = String.valueOf(cell.getNumericCellValue());
                return s2;
            }
        case NUMERIC:// 数字 ,尝试转日期
            short format = cell.getCellStyle().getDataFormat();
            // System.out.println("format:" + format + ";;;;;value:" +
            // cell.getNumericCellValue());

            SimpleDateFormat sdf = null;
            if (format == 14 || format == 31 || format == 57 || format == 58 || (176 <= format && format <= 178)|| (182 <= format && format <= 196) || (210 <= format && format <= 213) || (208 == format)) { // 日期
                sdf = new SimpleDateFormat("yyyy-MM-dd");
            } else if (format == 20 || format == 32 || format == 183 || (200 <= format && format <= 209)) { // 时间
                sdf = new SimpleDateFormat("HH:mm");
            } else { // 不是日期格式
                return String.valueOf(cell.getNumericCellValue());
            }
            double value = cell.getNumericCellValue();
            Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
            if (date == null) {
                return null;
            }
            String result = "";
            try {
                result = sdf.format(date);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
            return result;

        default:
            return cell.toString();
        }
    }

3,文件会被做各种未知修改,程序“皮实耐操”优于效率,所谓的鲁棒性要好。
通常用标题栏来确定数据位置,而不是去固定位置找数据,因为经常会有未知栏被插入文件。

4,不要在一个文件里面集成太多内容,宁可为不同用户生成不同文件,不要生成一个大杂烩给所有用户。
因为,后期不!好!改!。找bug,加新功能会要你命的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值