Jacen_Lin 2022-01-05 21:15 采纳率: 0%
浏览 23
已结题

POI 如何读取保护文件(xlsx)公式结果(语言-java)

poi读取保护xlsx时锁定单元格时公式

/**
     * 读取excel
     *
     * @param inputStream 输入流数据
     * @return List<Map<String,String>> 数据以表头和值的形式保存到map中
     */
    public static List<Map<String,String>> getAllData(InputStream inputStream,Boolean flagTitle){
        List<Map<String,String>> list = new ArrayList();
        XSSFWorkbook wb;
        String poiLockPassword = PropertyUtils.getString("poiLock_password");
        //表头所在列索引
        try {
//            OPOIFSFileSystem fs = new OPOIFSFileSystem(inputStream);
//            EncryptionInfo info = new EncryptionInfo(fs);
//            Decryptor d = Decryptor.getInstance(info);
//            wb = (XSSFWorkbook) WorkbookFactory.create(inputStream, poiLockPassword);
            wb = new XSSFWorkbook(inputStream);
            for(int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++){
                XSSFSheet st = wb.getSheetAt(sheetIndex);
//                if(st.getProtect()){
//                    boolean b = st.validateSheetPassword(poiLockPassword);
//                    st.protectSheet(null);
//                    st.disableLocking();
//                    st.lockSelectLockedCells(false);
//                    st.lockSelectUnlockedCells(true);
//                }
                List<Map<String,String>> sheetData = flagTitle?readSheetDataTow(wb, st):readSheetData(wb, st);
                list.addAll(sheetData);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e);
        }finally{
            //关闭流
            if(null!=inputStream){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error(e);
                }
            }
        }
        return list;
    }

private static List<Map<String,String>> readSheetData(XSSFWorkbook wb, XSSFSheet st){

        XSSFCell cell;
        List<Map<String,String>> list = new ArrayList();
        //表头所在列索引
        Map<Integer,String> cmCellIndex = new HashMap();

        for(int rowIndex=0; rowIndex<=st.getLastRowNum(); rowIndex++){//sheet中遍历所有的行

            Map<String,String> rowCellValue = new HashMap();
            XSSFRow row = st.getRow(rowIndex);//row为整行数据
            if(row == null){
                continue;
            }

            int colCnt = row.getLastCellNum();//一行有几列
            int emptyCnt = 0;    // 计算空白的单元格数

            for(int columnIndex = 0; columnIndex < colCnt; columnIndex++){//行中遍历所有的列
                cell = row.getCell(columnIndex);
                String value = getCellFormatValue(cell);
                //将excel表头所在列位置记录
                if(rowIndex == 0){
                    if(StringUtils.hasText(value)){
                        cmCellIndex.put(columnIndex, value);//记录第一行所有的cell
                    }
                }else{
                    //将excel文档中的标题和值key-value保存
                    //String colName = cmCellIndex.get(columnIndex);
                    //if(colName != null){
                    rowCellValue.put(String.valueOf(columnIndex+1), value);
                    //}

                    if(!StringUtils.hasText(value)){
                        emptyCnt++;
                    }
                }
            }

            // 首行或整行是空的排除掉
            if(rowIndex != 0 && emptyCnt != colCnt){
                //if(rowIndex!=0){
                list.add(rowCellValue);
            }
        }

        return list;
    }

/**
     * 获取cell的值
     *
     * @param cell
     * @return
     */
    private static String getCellFormatValue(XSSFCell cell){
        String cellvalue = "";
        if (cell != null) {
            cell.getCellStyle().setLocked(false);
            // 判断当前Cell的Type
            switch (cell.getCellType()) {
                // 如果当前Cell的Type为NUMERIC
                case XSSFCell.CELL_TYPE_NUMERIC:
                case XSSFCell.CELL_TYPE_FORMULA: {
                    try {
                        /*
                         * 此处判断使用公式生成的字符串有问题,因为XSSFDateUtil.isCellDateFormatted(cell)判断过程中cell
                         * .getNumericCellValue();方法会抛出java.lang.NumberFormatException异常
                         */
                        // 判断当前的cell是否为Date
                        if (DateUtil.isCellDateFormatted(cell)) {
                            // 如果是Date类型则,转化为Data格式

                            //方法1:这样子的data格式是带时分秒的:2011-10-12 0:00:00
                            //cellvalue = cell.getDateCellValue().toLocaleString();

                            //方法2:这样子的data格式是不带带时分秒的:2011-10-12
                            Date date = cell.getDateCellValue();
                            SimpleDateFormat sdf = new SimpleDateFormat(DATE_READ_FORMAT);
                            cellvalue = sdf.format(date);
                        }
                        // 如果是纯数字
                        else {
                            // 取得当前Cell的数值
                            long longVal = Math.round(cell.getNumericCellValue());
                            Double doubleVal = cell.getNumericCellValue();
                            if(Double.parseDouble(longVal + ".0") == doubleVal){
                                cellvalue = String.valueOf(longVal);
                            }else{
                                cellvalue = String.valueOf(doubleVal);
                            }
                        }
                        break;
                    } catch (IllegalStateException e) {
                        // 发生转换异常,字符串无法转换为数字,以字符串方式解析单元格内容
                        cellvalue = String.valueOf(cell.getRichStringCellValue());
                    }
                    break;

                }
                // 如果当前Cell的Type为STRIN
                case XSSFCell.CELL_TYPE_STRING:
                    // 取得当前的Cell字符串
                    cellvalue = cell.getRichStringCellValue().getString();
                    break;
                // 默认的Cell值
                default:
                    cellvalue = " ";
            }
        } else {
            cellvalue = "";
        }

        return com.spphins.common.util.StringUtils.deleteWhitespace(cellvalue);
    }

解锁和解除保护使用 cell.getCellStyle().setLocked(false);
还是获取不到公式计算结果。
cell.getNumericCellValue();到这一步结果直接变成0了。

  • 写回答

1条回答 默认 最新

  • 有问必答小助手 2022-01-07 10:33
    关注

    你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


    本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。


    因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。

    评论

报告相同问题?

问题事件

  • 系统已结题 1月13日
  • 创建了问题 1月5日

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料