POI导入具有合并了单元格的Excel
2024-08-26 15:13:28
POI进行单行单行地导入的数据在网上有许多的文章,但是要导入一个具有合并单元格的excel貌似比较难找。刚好最近完成了这样的一个需求,要求导入具有合并单元格的excel:
/**
* 读取excel数据,调用这方法开始
* @param is
* @param indexNum 至少需要多少列数据
*/
public static List<Object[]> readExcelToObj(InputStream is,int indexNum) { Workbook wb = null;
List<Object[]> objArrList = null;
try {
objArrList = new ArrayList<>();
wb = WorkbookFactory.create(is);
readExcel(wb, 0, 0, 0,objArrList,indexNum);
} catch (InvalidFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return objArrList;
}
/**
* 读取excel文件
* @param wb
* @param sheetIndex sheet页下标:从0开始
* @param startReadLine 开始读取的行:从0开始
* @param tailLine 去除最后读取的行
*/
public static void readExcel(Workbook wb,int sheetIndex, int startReadLine, int tailLine, List<Object[]> objArrList, int indexNum) {
Sheet sheet = wb.getSheetAt(sheetIndex);
Row row = null; for(int i=startReadLine; i<sheet.getLastRowNum()-tailLine+1; i++) {
row = sheet.getRow(i);
List<Object> objList = new ArrayList<>();
for(int j = 0 ; j<row.getLastCellNum();j++) {
//for(Cell c : row) {
Cell c = row.getCell(j);
if(c==null){
objList.add("");
continue;
}
boolean isMerge = isMergedRegion(sheet, i, c.getColumnIndex());
//判断是否具有合并单元格
if(isMerge) {
String rs = getMergedRegionValue(sheet, row.getRowNum(), c.getColumnIndex());
objList.add(rs);
}else {
objList.add(getCellValue(c));
} }
while(objList.size()<indexNum){
objList.add("");
}
objArrList.add(objList.toArray());
}
}
/**
* 获取合并单元格的值
* @param sheet
* @param row
* @param column
* @return
*/
public static String getMergedRegionValue(Sheet sheet ,int row , int column){
int sheetMergeCount = sheet.getNumMergedRegions(); for(int i = 0 ; i < sheetMergeCount ; i++){
CellRangeAddress ca = sheet.getMergedRegion(i);
int firstColumn = ca.getFirstColumn();
int lastColumn = ca.getLastColumn();
int firstRow = ca.getFirstRow();
int lastRow = ca.getLastRow(); if(row >= firstRow && row <= lastRow){ if(column >= firstColumn && column <= lastColumn){
Row fRow = sheet.getRow(firstRow);
Cell fCell = fRow.getCell(firstColumn);
return getCellValue(fCell) ;
}
}
} return null ;
}
/**
* 判断指定的单元格是否是合并单元格
* @param sheet
* @param row 行下标
* @param column 列下标
* @return
*/
public static boolean isMergedRegion(Sheet sheet,int row ,int column) {
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 true;
}
}
}
return false;
}
/**
* 获取单元格的值
* @param cell
* @return
*/
public static String getCellValue(Cell cell){ if(cell == null) return ""; if(cell.getCellType() == Cell.CELL_TYPE_STRING){ return cell.getStringCellValue(); }else if(cell.getCellType() == Cell.CELL_TYPE_BOOLEAN){ return String.valueOf(cell.getBooleanCellValue()); }else if(cell.getCellType() == Cell.CELL_TYPE_FORMULA){ return cell.getCellFormula() ; }else if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){ return String.valueOf(cell.getNumericCellValue()); }
return "";
}
注意:这导入功能也适用于单行读取,直接调用 readExcelToObj() 方法即可;参数1:传入excel文件的输入流;参数2:指定你希望至少要读入多少列数据(比如传入个0,就代表:如果你有的行只有3列数据的话,那么获得的数组长度就只有3;如果你传入了10,那些只有3列的数据会自动填充空字符串给数组,使每个数组最小长度为10);
最新文章
- 使用Java字节流拷贝文件
- php wampserver 80 端口无法开启的解决方法
- 一句话概括下spring框架及spring cloud框架主要组件
- bash 截取字符串
- 通过Jexus 部署 dotnetcore
- The method getDispatcherType() is undefined for the type HttpServletRequest 升级到tomcat8(转)
- windows管道
- matplotlib学习之绘图基础
- vc++调用web服务传输文件
- 使用supervisor管理进程
- UNIX环境高级编程——epoll函数使用详解
- .NET Core玩转机器学习
- <;五>;企业级开源仓库nexus3实战应用–使用nexus3配置npm私有仓库
- Docket 使用命令
- bzoj5281/luogu4377 Talent Show (01分数规划+背包dp)
- python绝对路径相对路径函数
- db2表空间及日志文件调整
- 进阶系列(12)—— C#异步编程
- 记一次坑爹的golang 二维map判断问题
- 搭建VueMint-ui框架