POI的读取EXCEL的【总结】

POI的读取EXcel的总结

最近的自己在做了一些关于EXcel的导入工作,正好总结一下我用到一些知识点

我首先说用到的方法

POI读取指定行列的方法

语法:

sheet.getRow(x): 获取第x

sheet.getRow(x).getCell(y): 获取第x行第y

eg:

 sheet.getRow(5).getCell(2).toString();   //获取第5行第2列数据

获取指定列_所有数据

sheet.getPhysicalNumberOfRows(): 返回物理定义的行数(不是工作表中的行数)这个要千万注意哈!~

sheet.getLastRowNum():这个是sheet页的最后一行,也就是整行数

/**
 * 获取到Excel里所有的编号
 */
List<String> list = new ArrayList<>();
// 将文件流传过来,变成workbook对象。
XSSFWorkbook wb = new XSSFWorkbook(file.getInputStream());
// 获得文本的sheet
XSSFSheet sheet = wb.getSheetAt(0);
// 获得sheet里所有的行数  (这个不准确会自动忽略中间的空行==> 不建议使用)
//int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
//这相当于获取一个sheet所有行数
int physicalNumberOfRows = sheet.getLastRowNum();
 
XSSFRow row  ;
// 循环每个行
for (int i = 0;i<physicalNumberOfRows;i++) {
    
    
   row = sheet.getRow(i);
   // 获取到每行的表格cell
   int physicalNumberOfCells = row.getPhysicalNumberOfCells();
   for (int k = 0; k < physicalNumberOfCells; k++) {
    
    
      // 转换一下cell的格式,防止出错
      row.getCell(k).setCellType(Cell.CELL_TYPE_STRING);
      // 获取到cell中的值
      list.add(row.getCell(k).getStringCellValue());
   }
}

获取指定行所有数据

sheet.getRow(i).getLastCellNum(): 是指第i

这里以获取EXCEL的一个sheet页所有信息为例

//空`sheet`不做操作,直接返回
if(sheet.getLastRowNum() == 0 &&  sheet.getPhysicalNumberOfRows() == 0){
    
    
    return;
}
//获取all  rows
int rows = sheet.getLastRowNum();
 

XSSFRow row  ;
// 循环每个行
for (int i = 0;i<physicalNumberOfRows;i++) {
    
    
   row = sheet.getRow(i);
    //判空处理,防止宝座
    if(row!=null){
    
    
        // 获取到每行的表格cell
       int cells = row.getLastCellNum();
       for (int k = 0; k < physicalNumberOfCells; k++) {
    
    
          // 转换一下cell的格式,防止出错
          row.getCell(k).setCellType(Cell.CELL_TYPE_STRING);
          // 获取到cell中的值
          list.add(row.getCell(k).getStringCellValue());
       }
    } 
   
}

案例分析(摘录而来)

需求: POI 导入订单 excel 空行or空数据处理并获取真实数据

就是删除EXcel中为空行,只保留有数据的Excel

扫描二维码关注公众号,回复: 17134457 查看本文章

目的解决getLastRowNum 拿到含空格的sheet中行数size

  • row = sheet.getRow(i) row == null (空行)

  • 旧的数据或数据格式,使用delete键删除后,row不会等于null,解析的结果是空字符串或其它(这是个坑)

    从而导致 size = getLastRowNum 最终可能会失真,

如何过滤掉不要的数据行,获取到真实的行号并将错误信息行反馈给用户===> 需要解决的

Solution:

  • 循环遍历取得sheet中全部数据存入list
  • 如果row = null ,也会创建一个map,将对应的字段全部置为空字符串
  • 如果row可能是上面情况,excel表中对应的内容会都是空字符串或其它,这时同样存入map
  • 正常数据也存入map
  • 遍历的同时,将行号row同时放入这个map(重要);

代码实现:

private Map<String, Object> analysisExcelToList(MultipartFile multipartFile) throws Exception {
    
    
        Workbook workbook = WorkbookFactory.create(multipartFile.getInputStream());
        Sheet sheet = workbook.getSheetAt(0);
        // getLastRowNum 拿到的可能不是真实的表size大小,有可能单元格清除内容后保留的单元格也会记录size大小
        int size = sheet.getLastRowNum();
        List<Map<String, String>> list = new ArrayList<>(size);
        Row buyerRow = sheet.getRow(1);
        // 获取客户名和订单类型
        String buyerName = POIUtils.getStringCellValue(buyerRow.getCell(1));
        String orderType = POIUtils.getStringCellValue(buyerRow.getCell(3));

        for (int i = 3; i <= size; i++) {
    
    
            Map map = new HashMap<>();
            Row row = sheet.getRow(i);
            // 若执行到行为空,将填充空数据(delete 删除的空行会保留格式,row不会等于null)
            if (row == null) {
    
    
                map.put("smallByrName", "");
                map.put("pdtAlias", "");
                map.put("weight", "");
                map.put("remark", "");
                continue;
            }
            map.put("smallByrName", POIUtils.getStringCellValue(row.getCell(1)));
            map.put("pdtAlias", POIUtils.getStringCellValue(row.getCell(2)));
            map.put("weight", POIUtils.getStringCellValue(row.getCell(3)));
            map.put("remark", POIUtils.getStringCellValue(row.getCell(4)));
            map.put("row", String.valueOf(i + 1));
            list.add(map);
        }
        // 删除空行(二级订单:smallByrName、pdtAlias、weight 三个参数同时为空)
        list.removeIf(e -> StringUtils.isBlank(e.get("smallByrName")) && StringUtils.isBlank(e.get("pdtAlias")) && StringUtils.isBlank(e.get("weight")));
        Map<String, Object> map = new HashMap<>();
        map.put("buyerName", buyerName);
        map.put("orderType", orderType);
        map.put("list", list);
        return map;
    }

获取表头标题列:(可忽略,自己学习)

XlsReader reader = new XlsReader(null, path);

public void impData(ImpFileInfo fileInfo, ImpCfg impCfg) throws Exception {
    
    
		record.appendDetailMes("解析文件开始:" + DateUtil.getNow("HH:mm:ss SSSS"));
		Path path = new Path(fileInfo.getFilePath());
		XlsReader reader = new XlsReader(null, path);
		reader.open();
    	
		Sheet sheet = reader.getSheetByName("sheet名称");
		if(null != sheet){
    
    
			if("利率互换日结单".equals(fileInfo.getFileName().substring(0, fileInfo.getFileName().indexOf(".")))){
    
    
				handleDataHtf(sheet);
			}else{
    
    
				if(fileInfo.getFileName().startsWith("云不V")){
    
    
					handleData(sheet);
				}else {
    
    
					handleData(sheet);
				}
			}
		}else {
    
    
			//STORY #157691 如果文件中包含“日结单”sheet名称则走旧模式,否则走新模式。
			Sheet yunSheet = reader.getSheetByName("yun");
			Sheet bvSheet = reader.getSheetByName("buV");
			//当汇总信息和结算信息同时存在,执行
			if(null!=yunSheet&&null!=bvSheet) {
    
    
				handleyunData(yunSheet,bvSheet);
			}
		}
		
		reader.close();
		record.appendDetailMes("解析文件结束:" + DateUtil.getNow("HH:mm:ss SSSS"));
		this.conn.setAutoCommit(false);
		record.appendDetailMes("删除临时表开始:" + DateUtil.getNow("HH:mm:ss SSSS"));
		deleteData(fileInfo);
		record.appendDetailMes("删除临时表结束:" + DateUtil.getNow("HH:mm:ss SSSS"));
		record.appendDetailMes("插入数据到正式表:" + DateUtil.getNow("HH:mm:ss SSSS"));
		saveData(fileInfo);//保存数据
		record.appendDetailMes("上传" + insertCount + "条数据。");
		BEN_RECORD_DETAIL_TEXT arugTitle = new BEN_RECORD_DETAIL_TEXT("上传" + insertCount + "条数据。", null, true);
		record.addDetailParent(arugTitle);
		this.conn.commit();
		this.conn.setAutoCommit(true);
		fileInfo.setOKTrans(true);
	}

当中的open方法: 进行EXcel的读取操作

/**
 * 普通读MS-Excel文档,以POI驱动读数据
 * 
 */
public class XlsReader extends BaseFileReader {
    
    
	
	private final String FILE_TEMP_IMP_ROOT_DIR = "yubuv/file/uploadtemp/";
	
	private Workbook workbook = null;

	public Workbook getWorkbook() {
    
    
		return workbook;
	}

	public void setWorkbook(Workbook workbook) {
    
    
		this.workbook = workbook;
	}

	private Map<String, Sheet> sheetMap = null;
	private List<Sheet> sheetList = null;
	private Sheet xlsSheet = null;
	private long rowIdx = 0;
	/**
	 * 是否为起始行
	 */
	private boolean isStartRow = false;
	/**
	 * 是否以开始标记作为起始位置判断条件(默认以行号判断起始位置)
	 */
	private boolean isStartMark = false;

	/**
	 * <源字段配置信息,对应单元格值>(用于获取特定单元格的值) 
	 */
	private Map<String, Object> fixedCellMap = null;

	/**
	 * 列头信息 读取Excel时如果是按伪列头方式读取,可设置列头起始行数,不填默认为第一行
	 */
	private Map<String, Integer> colIndexMap = new HashMap<String, Integer>();

	public XlsReader(FileCfg fileCfg, Path path) {
    
    
		super(fileCfg, path);
	}

	public Sheet getSheetByName(String sheetName) {
    
    
		return sheetMap.get(sheetName);
	}

	@Override
	public void setImpTable(ImpTable impTable) {
    
    
		super.setImpTable(impTable);
		boolean hasFakeColumn = false;
		if (impTable.getFieldList() != null
				&& impTable.getFieldList().getLst_Field() != null) {
    
    
			for (ImpField field : impTable.getFieldList().getLst_Field()) {
    
    
				if (field.getC_SF_CODE().startsWith("NAME")) {
    
    
					hasFakeColumn = true;
					break;
				}
			}
		}

		// //读取Excel时如果是按伪列头方式读取,可设置列头起始行数,不填默认为第一行
		if (hasFakeColumn) {
    
    
			try {
    
    
				initColumnIndexMap(
						impTable.getStratMark().getColHeadStartRow(),
						impTable.getC_Src_Code());

				for (ImpField field : impTable.getFieldList().getLst_Field()) {
    
    
					if (field.getC_SF_CODE().startsWith("NAME")) {
    
    
						String sfCode = field.getC_SF_CODE();
						String colName = sfCode.substring("NAME(".length(),
								sfCode.lastIndexOf(")")).trim();
						if (!colIndexMap.containsKey(colName) && !field.isIgnorable())
							throw new YssRuntimeException("列头:" + colName
									+ "不存在, 请检查配置文件");
						if(colIndexMap.containsKey(colName)){
    
    
							int index = colIndexMap.get(colName);
							field.setC_SF_CODE("INDEX(" + index + ")");
						}
						
					}
				}

			} catch (Exception e) {
    
    
				throw new YssRuntimeException("初始化列头信息失败:" + e.getMessage(), e);
			}
		}
	}

	/**
	 * 初始化列头信息 读取Excel时如果是按伪列头方式读取,可设置列头起始行数,不填默认为第一行
	 * @param startRow
	 * @param name
	 * @throws Exception
	 */
	private void initColumnIndexMap(int startRow, String name) throws Exception {
    
    
		if (startRow < 1)
			startRow = 1;
		if (StringUtil.IsNullOrEmpty(name)) {
    
    
			name = workbook.getSheetAt(0).getSheetName();
		}
		if (!sheetMap.containsKey(name)) {
    
    
			throw new Exception("Not Found " + name + " Sheet.");
		}
		xlsSheet = sheetMap.get(name);
		colIndexMap.clear();
		Row row = xlsSheet.getRow(startRow - 1);
		if (row != null) {
    
    
			for (int colIndex = 0; colIndex < row.getLastCellNum(); colIndex++) {
    
    
				Cell cell = row.getCell(colIndex);
				if (cell != null) {
    
    
					if(cell.getCellType() != Cell.CELL_TYPE_STRING){
    
    
						cell.setCellType(Cell.CELL_TYPE_STRING);
					}
					colIndexMap.put(cell.getStringCellValue() == null ? ""
							: cell.getStringCellValue().trim(), cell
							.getColumnIndex() + 1);
				}
			}
		}
	}



	@Override
	public void close() {
    
    
		workbook = null;
		sheetMap = null;
		sheetList = null;
		xlsSheet = null;
	}

    //这个方法仔细读读
	@Override
	public void open() throws Exception {
    
    
		String filePath = path.getFilePath();
		filePath = PreventInjectionUtility.pathManipulation(filePath);
		FileInputStream fs = null;
		InputStream stream = null;
		try {
    
    
			fs = new FileInputStream(filePath);
			stream = new BufferedInputStream(fs);
			String suffix = filePath.substring(filePath.lastIndexOf("."));
			if (".xlsx".equalsIgnoreCase(suffix)) {
    
    
				try {
    
    
					workbook = new XSSFWorkbook(stream);
				} catch (Exception e) {
    
    
					// 这里流会会被关闭,应该重新打开
					filePath = PreventInjectionUtility.pathManipulation(filePath);
					fs = new FileInputStream(filePath);
					stream = new BufferedInputStream(fs);
					workbook = new HSSFWorkbook(stream);
				}
			} else {
    
    
				try {
    
    
					workbook = new HSSFWorkbook(stream);
				} catch (Exception e) {
    
    
					if (e.getMessage() != null
							&& ((e.getMessage().startsWith("Initialisation of record") 
									&& (e.getMessage().endsWith("still to be read") || e.getMessage().endsWith("still to be read.")))
									|| e.getMessage().contains("Found EOFRecord before WindowTwoRecord was encountered")
									|| e.getMessage().contains("The supplied spreadsheet seems to be Excel 5.0/7.0 (BIFF5) format"))) {
    
    
						// 用jxs处理下,再读取
						jxl.Workbook jxlWorkbook = null;
						jxl.write.WritableWorkbook wwb = null;
						filePath = PreventInjectionUtility.pathManipulation(filePath);
						File originFile = new File(filePath);
						long currentTimeMillis = System.currentTimeMillis();
						
						String tmpPath = FILE_TEMP_IMP_ROOT_DIR + currentTimeMillis + "/" + fileCfg.getCfgCode() + "/"
								+ UUID.randomUUID().toString();
						FileStorePathUtil fileStorePathUtil = new FileStorePathUtil(tmpPath);
						String fullPathName = fileStorePathUtil.getFilePath();
						if(fullPathName.endsWith("/")){
    
    
							fullPathName = fullPathName.substring(0, fullPathName.length() - 1);
						}
						
						File tmpFile = new File(fullPathName
								+ File.separator
								+ System.currentTimeMillis() + ".xls");
						try {
    
    
							jxl.WorkbookSettings workbookSettings = new jxl.WorkbookSettings();
							workbookSettings.setEncoding("GBK");
							jxlWorkbook = jxl.Workbook.getWorkbook(originFile, workbookSettings);
							// 最后一步:关闭资源
							wwb = jxl.Workbook.createWorkbook(tmpFile,
									jxlWorkbook);
							wwb.write();
							wwb.close();
							fs = new FileInputStream(tmpFile);
							stream = new BufferedInputStream(fs);
							workbook = new HSSFWorkbook(stream);
						} catch (Exception e3) {
    
    
							throw new Exception("用jxl处理后读取报错:"
									+ e3.getMessage(), e3);
						} finally {
    
    
							if (jxlWorkbook != null)
								jxlWorkbook.close();
							if (wwb != null) {
    
    
								try {
    
    
									wwb.close();
								} catch (Exception e4) {
    
    
								}
							}
							tmpFile.delete();
						}
					} else if (e.getMessage() != null
							&& e.getMessage().startsWith(
									"Invalid header signature")
							&& e.getMessage()
									.endsWith(
											"Your file appears not to be a valid OLE2 document")) {
    
    
						// // 对于xml格式的xls,进行异常捕捉
						readXmlExcelToHtmlTable(filePath);
					} else {
    
    
						// 这里流会会被关闭,应该重新打开
						filePath = PreventInjectionUtility.pathManipulation(filePath);
						fs = new FileInputStream(filePath);
						stream = new BufferedInputStream(fs);
						workbook = new XSSFWorkbook(stream);
					}
				}
			}
			if (workbook != null) {
    
    
				int sheetCount = workbook.getNumberOfSheets();
				sheetMap = new HashMap<String, Sheet>();
				sheetList = new ArrayList<Sheet>();
				for (int i = 0; i < sheetCount; i++) {
    
    
					Sheet xlsSheet = workbook.getSheetAt(i);
					sheetMap.put(xlsSheet.getSheetName(), xlsSheet);
					sheetList.add(xlsSheet);
				}
			}
		} catch (Exception e) {
    
    
			throw e;
		} finally {
    
    
			CloseUtil.close(fs);
			CloseUtil.close(stream);
		}
	}

	/**
	 * 将excel里面数据保存至文件中
	 * 
	 * @param fileName
	 * @throws Exception
	 */
	public void save(String fileName) throws Exception {
    
    
		fileName = PreventInjectionUtility.pathManipulation(fileName);
		FileOutputStream fs = new FileOutputStream(fileName);
		OutputStream stream = new BufferedOutputStream(fs);
		try {
    
    
			this.workbook.write(stream);
		} catch (Exception e) {
    
    
			throw e;
		} finally {
    
    
			if (stream != null)
				stream.close();
			if (fs != null)
				fs.close();
		}
	}

	@Override
	public boolean readDataRow(List<DataColumn> lstColumns, DataRow newRow)
			throws Exception {
    
    
		int cellValueCount = 0; // 记录单元格有多少个有效值
		try {
    
    
			Row xlsRow = xlsSheet.getRow((int) rowIdx);
			if (xlsRow == null)
				return false;
			int cellCount = xlsRow.getLastCellNum();
			for (DataColumn column : lstColumns) {
    
    
				Object objValue = null;
				// 这里判断是否是固定列,如果是固定列,就不再去读Excel的内容了
				boolean isFixColumn = false;// 是固定内容的列
				if (null != column.getDataColName()
						&& column.getDataColName().startsWith("FIX")) {
    
    
					isFixColumn = true;
				}

				// 根据列的序号
				int colIdx = column.getStartIndex() - 1;
				if (cellCount > colIdx || isFixColumn) {
    
    
					if (isFixColumn) {
    
    
						objValue = column.getDefValue();// 取默认值
					} else {
    
    
						Cell xlsCell = xlsRow.getCell(colIdx);
						if (xlsCell != null) {
    
    
							// 处理合并单元格 
							if (isStartMark) {
    
    
								xlsCell = getMergedCell(xlsSheet, xlsCell);
							}

							if (xlsCell.getCellType() == Cell.CELL_TYPE_NUMERIC
									|| xlsCell.getCellType() == Cell.CELL_TYPE_FORMULA) {
    
    
								String cellFormatStr = xlsCell.getCellStyle()
										.getDataFormatString();
								if (!"General".equalsIgnoreCase(cellFormatStr)
										&& !"@".equalsIgnoreCase(cellFormatStr)) {
    
    
									// cellFormatStr不为空,才走下面逻辑
									if (!"".equalsIgnoreCase(cellFormatStr)
											&& cellFormatStr != null) {
    
    
										if (cellFormatStr.indexOf("0") > -1
												|| cellFormatStr.indexOf("0.") > -1
												|| cellFormatStr.indexOf("#0") > -1
												|| cellFormatStr.indexOf("#.") > -1// 支持#,###.##格式的数值型
																					
												|| cellFormatStr.indexOf("#") > -1)
											// 增加异常处理,例如:="中英益利资产管理股份有限公司-"&B9,转换为string
											try {
    
    
												objValue = xlsCell
														.getNumericCellValue();
												if (column.getDataType()==java.util.Date.class) {
    
    
													String tmp = objValue+"";
													if (tmp.endsWith(".0")) {
    
    
														objValue = tmp.substring(0, tmp.length()-2);
													}
												}else if(column.getDataType() == String.class && cellFormatStr.equals("000000")){
    
    
													为了减少影响暂时写死,这块后续有要求可拓展
													DecimalFormat df = new DecimalFormat("000000");
											        objValue = df.format(objValue);
												}
											} catch (Exception e) {
    
    
												objValue = xlsCell
														.getStringCellValue();
											}
										else
											// 日期类型输出
											objValue = xlsCell
													.getDateCellValue();
									} else {
    
    
										if (column.getDataType() == java.util.Date.class) {
    
    
											objValue = xlsCell
													.getDateCellValue();
										} else {
    
    
											objValue = xlsCell
													.getNumericCellValue();
										}
									}
								} else {
    
    
									if (column.getDataType() == java.util.Date.class) {
    
    
										// 日期类型转换,通过数值类型转换,这里的日期没有标识格式字符串为General
										try {
    
    
											objValue = xlsCell
													.getNumericCellValue();
											objValue = YssFun
													.toDate(YssFun.formatNumber(
															(Double) objValue, "#"),
															"yyyyMMdd");
										} catch (Exception e) {
    
    
											// 其他类型,统一按字符类型输出
											if(StringUtil.IsNullOrEmpty(column.getDataFormat())){
    
    
												objValue = YssFun
														.toDate(YssFun.formatNumber(
																(Double) objValue, "#"),
																"yyyyMMdd");
											}else{
    
    
												objValue = YssFun
														.toDate(xlsCell.getStringCellValue(), column.getDataFormat());
											}
										}
										
									} else if (column.getDataType() == String.class) {
    
    
										xlsCell.setCellType(Cell.CELL_TYPE_STRING);
										objValue = xlsCell.getStringCellValue();
									} else {
    
    
										// 数值类型输出
                                        if (xlsCell.getCellType() == Cell.CELL_TYPE_FORMULA){
    
    
                                            xlsCell.setCellType(Cell.CELL_TYPE_STRING);
                                            objValue = Double.parseDouble(xlsCell.getStringCellValue());
                                        }else {
    
    
                                            objValue = xlsCell.getNumericCellValue();
                                        }
									}
								}
							} else if (xlsCell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
    
    
								// 布尔类型输出
								objValue = xlsCell.getBooleanCellValue();
							} else {
    
    
								// 其他类型,统一按字符类型输出
								objValue = xlsCell.getStringCellValue();
							}
						}
                    }

					checkSpecialColumn(column, objValue);
					newRow.addField(column.getColumnName(), objValue);
					// if (!StringUtil.IsNullOrEmpty(objValue == null ? null :
					// String
					// .valueOf(objValue)))
					// cellValueCount++;
					// 全是空格的行不导入,全角空格放入IsNullOrEmptyT 方法内判断
					if (!StringUtil.IsNullOrEmptyT(objValue == null ? null
							: String.valueOf(objValue)))
						cellValueCount++;
				}
			}
		} catch (Exception e) {
    
    
			String msg = "sheet:" + impTable.getC_Src_Code() + ", row:" + (rowIdx + 1) + "读取异常:" + e.getMessage();
			throw new Exception(msg, e);
		}
		return cellValueCount > 0 ? true : false;
	}

	@Override
	public boolean nextRow(long rowIndex) throws Exception {
    
    
		// 当以开始标记作为起始行时,行号不能由外部传入 
		if (isStartMark) {
    
    
			this.rowIdx++;
		} else {
    
    
			this.rowIdx = rowIndex;
		}
		return xlsSheet.getLastRowNum() >= rowIndex;
	}

	@Override
	public void currFileObj(String name, ImpConvertPojo convrtMode)
			throws Exception {
    
    
		if (StringUtil.IsNullOrEmpty(name)) {
    
    
			name = workbook.getSheetAt(0).getSheetName();
		}
		if (!sheetMap.containsKey(name)) {
    
    
			throw new Exception("Not Found " + name + " Sheet.");
		}
		xlsSheet = sheetMap.get(name);
		isStartRow = false;
		isStartMark = false;
		rowIdx = 0;
	}

	/**
	 * 获取sheet中的所有row
	 * 
	 * @param sheetName
	 * @return
	 */
	public List<Row> getAllRowsFromSheet(String sheetName) {
    
    
		List<Row> rows = new ArrayList<Row>();

		int rowFirst = 0;
		int rowLast = 0;

		Sheet sheet = this.sheetMap.get(sheetName);
		if (sheet == null) {
    
    
			return rows;
		}
		rowFirst = sheet.getFirstRowNum();
		rowLast = sheet.getLastRowNum();

		for (int crIdx = rowFirst; crIdx <= rowLast; crIdx++) {
    
    
			Row curRow = sheet.getRow(crIdx);
			if (curRow == null) {
    
    
				continue;
			}
			rows.add(curRow);
		}

		return rows;
	}

	/**
	 * 获取行中单元格的所有注释
	 * 
	 * @param row
	 * @return
	 */
	public List<Comment> getAllCommentFrom(Row row) {
    
    
		List<Comment> comments = new ArrayList<Comment>();

		int rowNum = row.getRowNum();
		int colFirst = row.getFirstCellNum();
		int colLast = row.getLastCellNum();

		for (int curCol = colFirst; curCol <= colLast; curCol++) {
    
    
			Comment comment = row.getSheet().getCellComment(rowNum, curCol);
			if (comment == null
					|| comment.getString().getString().trim().length() == 0) {
    
    
				continue;
			}
			comments.add(comment);
		}

		return comments;
	}

	public List<Cell> getAllCellFrom(Row row) {
    
    
		List<Cell> cells = new ArrayList<Cell>();

		int colFirst = row.getFirstCellNum();
		int colLast = row.getLastCellNum();

		for (int curCol = colFirst; curCol <= colLast; curCol++) {
    
    
			Cell cell = row.getCell(curCol);
			if (cell == null) {
    
    
				continue;
			}
			cells.add(cell);
		}
		return cells;
	}

	public Map<String, Sheet> getSheetMap() {
    
    
		return this.sheetMap;
	}

	@Override
	public boolean checkStartMark(ReadMark startMark) throws Exception {
    
    
		// 支持开始标记作为起始行,支持正则表达式
		if (startMark.getMarkType() == MarkEnum.Mark
				&& !StringUtil.IsNullOrEmptyT(startMark.getMarkValue())) {
    
    
			isStartMark = true;
			if (!isStartRow) {
    
    
				String regex = startMark.getMarkValue().replaceAll("\\*",
						"\\(\\.\\)\\*");
				for (long i = rowIdx; i < xlsSheet.getLastRowNum(); i++) {
    
    
					Row xlsRow = xlsSheet.getRow((int) i);
					if (xlsRow != null
							&& xlsRow.getCell(0) != null
							&& xlsRow.getCell(0).getCellType() == Cell.CELL_TYPE_STRING) {
    
    
						String cellText = xlsRow.getCell(0)
								.getStringCellValue();
						if (cellText.matches(regex)) {
    
    
							isStartRow = true;
							rowIdx = i;
							break;
						}
					}
				}
			}
		} else {
    
    
			isStartRow = true;
		}

		return isStartRow;
	}

	@Override
	public boolean checkEndMark(String endMark) throws Exception {
    
    
		if (!StringUtil.IsNullOrEmpty(endMark)) {
    
    
			Row xlsRow = xlsSheet.getRow((int) rowIdx);
			if (xlsRow != null && xlsRow.getCell(0) != null
					&& xlsRow.getCell(0).getCellType() == Cell.CELL_TYPE_STRING) {
    
    
				String cellText = xlsRow.getCell(0).getStringCellValue();
				if (endMark.endsWith("*")) {
    
    
					return cellText != null
							&& cellText.startsWith(endMark.replace("*", ""));
				} else {
    
    
					return endMark.equalsIgnoreCase(cellText);
				}
			}
		}
		return false;
	}

	/**
	 * 获取合并单元格
	 * @param sheet
	 *            分页
	 * @param cell
	 *            单元格
	 * @return
	 */
	private Cell getMergedCell(Sheet sheet, Cell cell) {
    
    
		int row = cell.getRowIndex();
		int column = cell.getColumnIndex();
		int sheetMergeCount = sheet.getNumMergedRegions();
		for (int i = 0; i < sheetMergeCount; i++) {
    
    
			CellRangeAddress range = sheet.getMergedRegion(i);
			int firstColumn = range.getFirstColumn();
			int lastColumn = range.getLastColumn();
			int firstRow = range.getFirstRow();
			int lastRow = range.getLastRow();
			if (row >= firstRow && row <= lastRow) {
    
    
				if (column >= firstColumn && column <= lastColumn) {
    
    
					return sheet.getRow(firstRow).getCell(firstColumn);
				}
			}
		}

		return cell;
	}

	/**
	 * 获取特定单元格的值
	 * @param fieldConfig
	 *            单元格配置信息
	 * @return
	 */
	private Object getFixedCellValue(String fieldConfig) {
    
    
		// 例:GETCELL("","人民币资产汇总",4,4) 获取以第一个分页 单元格("人民币资产汇总")为坐标原点,第4行,第4列单元格的值
		if (fixedCellMap == null) {
    
    
			fixedCellMap = new HashMap<String, Object>();
		}
		if (fixedCellMap.containsKey(fieldConfig)) {
    
    
			return fixedCellMap.get(fieldConfig);
		} else {
    
    
			String[] params = fieldConfig.replaceAll("\"", "")
					.replace("GETCELL(", "").replace(")", "").split(",");
			String sheetName = params[0];
			if (StringUtil.IsNullOrEmptyT(sheetName)) {
    
    
				sheetName = workbook.getSheetAt(0).getSheetName();
			}
			Sheet sheet = sheetMap.get(sheetName);
			String regex = params[1];
			int rowIndex = Integer.valueOf(params[2]);
			int colIndex = Integer.valueOf(params[3]) - 1;
			for (int row = 0; row <= sheet.getLastRowNum(); row++) {
    
    
				Row xlsRow = sheet.getRow(row);
				if (xlsRow == null)
					continue;
				if (xlsRow.getCell(0) != null && xlsRow.getCell(0).getStringCellValue().matches(regex)) {
    
    
					if (row + rowIndex < sheet.getLastRowNum()) {
    
    
						Row targetRow = sheet.getRow(row + rowIndex);
						if (colIndex <= targetRow.getLastCellNum()) {
    
    
							Cell cell = targetRow.getCell(colIndex);
							cell.setCellType(Cell.CELL_TYPE_STRING);
							String value = cell.getStringCellValue();
							fixedCellMap.put(fieldConfig, value);
							return value;
						}
					}

					break;
				}
			}
		}

		return "";
	}
	
	/**
	 *  获取某个sheet页某行某列数据 
	 * 示例1:
	 * ${GETFIXSUBCELL("",1,1)}
	 * 取第一行第一列的数据
	 * 取值:“2019年3月21日-2019年6月20日认/申购资金T日孳生利息数据”
	 * 示例2:
	 * ${GETFIXSUBCELL("",1,1,"-","日","yyyy年MM月dd日")}
	 * ${GETFIXSUBCELL(sheet分页,第一行,第一列,取-之后, 取到日,数据日期格式)}
	 * 取第一个sheet页的第一第一列行的数据,若不存在“-”则:截取字符串开始至“日”的字符串;若存在“-”则:截取字符串“-”之后至“日”的字符串
	 * 取值:2019年6月20日   或  2019年05月07日
	 * @param fieldConfig 列值
	 * @param dataType  列类型
	 * @return
	 * @throws Exception
	 * 
	 */
	private Object getFixedSubCellValue(String fieldConfig,Class dataType) throws Exception{
    
    
		if(fixedCellMap == null){
    
    
			fixedCellMap = new HashMap<String, Object>();
		}
		if(fixedCellMap.containsKey(fieldConfig)){
    
    
			return fixedCellMap.get(fieldConfig);
		} else {
    
    
			String[] params = fieldConfig.replaceAll("\"", "").replace("GETFIXSUBCELL(", "").replace(")", "").split(",");
			String sheetName = params[0]; //sheet分页
			if (StringUtil.IsNullOrEmptyT(sheetName)) {
    
    
				sheetName = workbook.getSheetAt(0).getSheetName();
			}
			Sheet sheet = sheetMap.get(sheetName);
			int rowIndex = Integer.valueOf(params[1])-1;//取值单元格所在行
			int colIndex = Integer.valueOf(params[2])-1;//取值单元格所在列
			String startStr =  params[3];//下标开始字符串
			String endStr =  params[4];//下标结束字符串
			String formatStr =  params[5];//日期格式
			Row targetRow = sheet.getRow(rowIndex);
			Object objValue = null;
			String value = targetRow.getCell(colIndex).getStringCellValue();
			objValue = value;
			if(!StringUtil.IsNullOrEmpty(value)){
    
    
				int indexStart = 0;
				int indexEnd = value.length()-1;
				if(value.contains(startStr)){
    
    
					indexStart = value.indexOf(startStr)+1;
				}
				if(value.contains(endStr)){
    
    
					indexEnd = value.indexOf(endStr,indexStart)+1;
				}
				value = value.substring(indexStart,indexEnd);
				if (dataType == java.util.Date.class && !StringUtil.IsNullOrEmpty(formatStr)) {
    
    
					objValue = YssFun.toDate(value, formatStr);
				}
			}
			fixedCellMap.put(fieldConfig, objValue);
			return objValue;
			
		}
	}

	// // xml格式的xls文件读取
	private void readXmlExcelToHtmlTable(String filePath) {
    
    
		FileInputStream fs = null;
		InputStream stream = null;
		FileInputStream fsXLS = null;
		InputStream streamXLS = null;
		File tmpFile = null;
		Scanner s = null;
		try {
    
    
			filePath = PreventInjectionUtility.pathManipulation(filePath);
			fs = new FileInputStream(filePath);
			stream = new BufferedInputStream(fs);
			StringBuilder html = new StringBuilder();
			s = new Scanner(stream, "utf-8");
			while (s.hasNext()) {
    
    
				html.append(s.nextLine());
			}

			String timeStamp = System.currentTimeMillis() + "";
			String tmpPath = FILE_TEMP_IMP_ROOT_DIR + timeStamp + "/" + fileCfg.getCfgCode() + "/"
					+ UUID.randomUUID().toString();
			FileStorePathUtil fileStorePathUtil = new FileStorePathUtil(tmpPath);
			String fullPathName = fileStorePathUtil.getFilePath();
			if(fullPathName.endsWith("/")){
    
    
				fullPathName = fullPathName.substring(0, fullPathName.length() - 1);
			}
			
			fullPathName = fullPathName + File.separator;
			
			HTMLTOExcel toolInstance = new HTMLTOExcel();
			toolInstance.toExcel(html.toString(), timeStamp, fullPathName);

			fsXLS = new FileInputStream(fullPathName + timeStamp + ".xls");
			streamXLS = new BufferedInputStream(fsXLS);
			workbook = new HSSFWorkbook(streamXLS);

			tmpFile = new File(fullPathName + timeStamp + ".xls");
		} catch (Exception ex) {
    
    
			try {
    
    
				throw new Exception("用jxl处理后读取报错:" + ex.getMessage(), ex);
			} catch (Exception e) {
    
    
				// TODO Auto-generated catch block
			}
		} finally {
    
    
			CloseUtil.close(fs);
			CloseUtil.close(stream);
			CloseUtil.close(s);
			CloseUtil.close(fsXLS);
			CloseUtil.close(streamXLS);
			
			if (tmpFile != null && tmpFile.exists()) {
    
    
				tmpFile.delete();
				FileUtil.deleteFile(tmpFile.getParentFile());
			}
		}
	}
	
	public void refreshSheets() {
    
    
		if (workbook != null) {
    
    
			if (sheetMap != null) {
    
    
				sheetMap.clear();
			} else {
    
    
				sheetMap = new HashMap<String, Sheet>();
			}
			
			if (sheetList != null) {
    
    
				sheetList.clear();
			} else {
    
    
				sheetList = new ArrayList<Sheet>();
			}
			
			int sheetCount = workbook.getNumberOfSheets();
			for (int i = 0; i < sheetCount; i++) {
    
    
				//  BUG #276579 后台全流程-功能点缺失
				Sheet xlsSheet = null;
				if(workbook instanceof SXSSFWorkbook){
    
    
					SXSSFWorkbook wk = (SXSSFWorkbook)workbook;
					xlsSheet = wk.getXSSFWorkbook().getSheetAt(i);
				}else{
    
    
					xlsSheet = workbook.getSheetAt(i);
				}
				sheetMap.put(xlsSheet.getSheetName(), xlsSheet);
				sheetList.add(xlsSheet);
			}
		}
	}
}

完结撒花!~

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43475992/article/details/133125045