POI使用
来源:互联网 发布:淘宝的xbox one手柄 编辑:程序博客网 时间:2024/06/04 19:12
Apache POI 使用小记
最近通过项目学习了Apache POI操作Excel的方法,记录一下方便日后使用。
首先导入Excel,生成WorkBook实例,之后便可以通过workbook读取Excel文档中的数据
public void importWorkBook(String filename){ WorkBook wb =null; wb = getWorkBook(filename); //检查导入的文件是哪一个版本的excel 创建对应的工作簿 if(wb == null) return; int numbs = wb.getNumberOfSheets(); //获取工作簿中的工作表数目 if(numbs > 0){ for(int i=0;i<numbs;i++){ //遍历每个工作表,进行相应的处理,比如将表中数据存入数据库 Sheet sheet = wb.getSheetAt(i); if(sheet!=null && sheetName.equals("工程造价指标(定额)")){ ... }else if(sheet!=null && sheetName.contains("工程造价指标(清单)")){ saveSheetToDb(sheet); }else{ continue; } } }}
生成WorkBook实例
private Workbook getWorkbook (String filename) { Workbook wb = null; if (filename == null || !filename.matches("^.+\\.(?i)((xls)|(xlsx))$")) { return null; } boolean isExcel2003 = true; /** 对文件的合法性进行验证 */ if (filename.matches("^.+\\.(?i)(xlsx)$")) { isExcel2003 = false; } /** 检查文件是否存在 */ File file = new File(filename); if (file == null || !file.exists()) { return null; } /** 根据版本选择创建Workbook的方式 */ try { wb = (Workbook) (isExcel2003 ? new HSSFWorkbook(new FileInputStream(file)) : new XSSFWorkbook(new FileInputStream(file))); } catch (FileNotFoundException e) { logger.error(e.getMessage(),e); } catch (IOException e) { logger.error(e.getMessage(),e); } return wb;}
将每张工作表中的数据保存到数据库中
private void saveSheetToDb(Sheet sheet){ Map<Integer, List<String>> rowMap = ExcelUtil.parseSheet(sheet); //导入的行集合 Map<String, Object> resMap= ExcelUtil.resMap; Map<String, Object> modelMap = (Map<String, Object>) resMap.get("model");//行模型集合 Map<String, Object> paramMap = (Map<String, Object>) resMap.get("param");//参数集合 List<Entity> resList = new ArrayList<>();//将要插入数据库的实体集合 //1 把行集合转化成一张或多张表格 List<List<Integer>> tableList = ExcelUtil.convertToTableList(rowMap, (List<String>) modelMap.get("tableHeadModelRow")); for (List<Integer> table : tableList) { /* 一张Sheet工作表中可能存在多张表格数据 根据定义的行模型集合modelMap和参数集合paramMap 找到需要的数据 将其封装为实体类Entiy */ Entity entity = new Entity(,,,,); resList.add(entity); } // 插入费用到数据库,如果实体数据条数大于200条,分批次插入 if (!resList.isEmpty()){ if (resList.size() > 200){ int size = resList.size(); int times = size % 200 == 0 ? size / 200 : size / 200 + 1; List<Entity> list = null; for (int i = 1; i <= times; i++){ if (i == times){ list = resList.subList((i -1) * 200, size); }else { list = resList.subList((i -1) * 200, i * 200); } zbFillDonorSpreadMapper.addBatchDonorSpread(list); } }else { zbFillDonorSpreadMapper.addBatchDonorSpread(resList); } }}
ExcelUtil parseSheet 方法
/** * 把页签解析成行集合 * @param sheet 页签 * @return 行集合,key为行索引,value为单元格集合 */public static Map<Integer, List<String>> parseSheet(Sheet sheet){ int rowNum = sheet.getLastRowNum() + 1; Map<Integer, List<String>> rowMap = new LinkedHashMap<>(); for (int r = 0; r < rowNum; r++){ Row row = sheet.getRow(r); List<String> cellList = new ArrayList<>(); boolean isDataList = false; for (int c = 0; c < row.getLastCellNum(); c++){ Cell cell = row.getCell(c); cell.setCellType(Cell.CELL_TYPE_STRING); String value = getCellValue(row, c); if (value == null){ cellList.add("?");//占位符 }else { if (Pattern.matches(IS_NUM_EXP, value)){ isDataList = true; } cellList.add(value.replaceAll("\\s", "")); } } if (isDataList){ cellList.add("dataRowFlag");//增加标识,用于识别数据行 } rowMap.put(r, cellList); } return rowMap;}
ExcelUtil convertToTableList 方法
/** * 把行集合按表头规则解析成多个表格 * @param rowMap 行集合 * @param tableHeadModelRow 表头模板 * @return 一个或多个表格的集合,集合保存的是行号,并不是数据 */public static List<List<Integer>> convertToTableList(Map<Integer, List<String>> rowMap, List<String> tableHeadModelRow){ List<List<Integer>> tableList = new ArrayList<>(); for (Map.Entry<Integer, List<String>> entry : rowMap.entrySet()) {//遍历所有行 List<String> row = entry.getValue(); int rowIndex = entry.getKey(); if (row.containsAll(tableHeadModelRow)){//如果行是表头,创建新的表 tableList.add(new ArrayList<Integer>()); tableList.get(tableList.size() - 1).add(rowIndex); }else if (tableList.size() > 0){//如果不是表头行,并且不为页签内第一个表头行上方的行 tableList.get(tableList.size() - 1).add(rowIndex); } } return tableList;}
下面列出resMap的数据 和 对应的一份excel文件截图
ExcelUtil.resMap = { model={ normTitleModelRow=[ 管理费, 利润, 风险费用 ], tableHeadModelRow=[ 项目编码, 项目名称, 计量单位, 综合单价 ], totalModelRow=[ 合计, —, — ], machineHeadModelRow=[ 3.机械 ], labourHeadModelRow=[ 1.人工 ], materialHeadModelRow=[ 2.材料 ], dataModelRow=[ dataRowFlag ], resTableHeadModelRow=[ 人工、材料及机械名称, 单位, 数量, 基价单价, 基价合价, 市场单价, 市场合价, 备注 ] }, param={ profitFee={ name=利润, cellOffset=0, rowOffset=-185 }, managementFee={ name=管理费, cellOffset=0, rowOffset=-185 }, unit={ name=单位, cellOffset=-1, rowOffset=-1 }, riskFee={ name=风险费用, cellOffset=0, rowOffset=-185 }, quatity={ name=数量, cellOffset=-1, rowOffset=-1 }, unitPrice={ name=市场单价, cellOffset=-1, rowOffset=-1 }, qdCode={ name=项目编码, cellOffset=1, rowOffset=0 }, costName={ name=人工、材料及机械名称, cellOffset=-1, rowOffset=-1 } }}
Excel文件截图 (1):
Excel文件截图 (2):
阅读全文
0 0
- 使用poi
- POI使用
- POI使用
- POI使用
- POI使用
- POI使用详解 Apache POI使用详解
- 【Java POI】1、Java POI的使用
- POI使用【z】
- poi使用实例
- POI的简单使用
- 使用POI操作Excel
- POI的简单使用
- POI简介-HSSH使用
- 使用POI操作EXCEl
- 使用poi解析Excel
- 使用poi导出excel
- 使用POI导出Excel
- 使用POI生成Excel
- 线性安全
- JDK、JRE、JVM
- ubuntu
- 判断一个数是否是完全数
- Navicat Premium 中文版注册码
- POI使用
- window多socket的连接
- Oracle数据库如何提高访问性能
- 【剑指Offer】面试题26:复杂链表的复制
- Ural 1091(48/600)
- Spring Boot 1.5.x 新特性 动态修改日志级别
- git内部原理
- Spring MVC + JPA + Hibernate + GlassFish V3 + MySQL 实现J2EE应用的常用配置模板详解
- Exception occurred during processing request: No Dialect mapping for JDBC type: -1