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);
}
}
}
}