欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

POI解析合并单元格

程序员文章站 2022-06-14 09:07:42
...
excel中的合并单元格其实就是首单元格,只不过该单元格增加了 rowspan和colspan两个属性。
并且把该单元格的高度和宽度变成(例如rowspan=2,colspan=3)2行,3列的的标尺长度,再把被合并的单元格(除了首单元格的其余5个单元格)隐藏。



public class ExcelUtils{


private void readExcel(Workbook wb) {
Sheet sheet = wb.getSheetAt(0);
Row row = null;

for(int i=0; i<sheet.getPhysicalNumberOfRows(); i++)
{
row = sheet.getRow(i);
for(int j = 0; j < row.getLastCellNum();j++)
{
Cell c = row.getCell(j);
boolean isMerge = isMergedRegion(sheet, i, c.getColumnIndex());
//判断是否具有合并单元格
if(isMerge) {
String rs = getMergedRegionValue(sheet, row.getRowNum(), c.getColumnIndex());
System.out.print(rs+" ");
}else {
System.out.print(c.getRichStringCellValue()+" ");
}
}

}

}

/**
* 获取合并单元格的值
* @param sheet
* @param row
* @param column
* @return
*/
public String getMergedRegionValue(Sheet sheet ,int row , int column){
int sheetMergeCount = sheet.getNumMergedRegions(); //获得该sheet所有合并单元格数量

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) ;
}
}
}
//如果该单元格行号列号不在任何一个合并区域,择返回null
return null ;
}

/**
* 判断合并了行
* @param sheet
* @param row
* @param column
* @return
*/
private boolean isMergedRow(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 sheet
* @param row 行下标
* @param column 列下标
* @return
*/
private 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;
}

/**
* 判断sheet页中是否含有合并单元格
* @param sheet
* @return
*/
private boolean hasMerged(Sheet sheet) {
return sheet.getNumMergedRegions() > 0 ? true : false;
}

/**
* 合并单元格
* @param sheet
* @param firstRow 开始行
* @param lastRow 结束行
* @param firstCol 开始列
* @param lastCol 结束列
*/
private void mergeRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
}

/**
* 获取单元格的值
* @param cell
* @return
*/
public 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 "";
}
}

}


原理:
通过sheet.getNumMergedRegions();获得所有合并单元格的数量,并且一一遍历,判断传入的单元格行下标和列下标是否在该合并单元格的范围内,如果在,则直接返回该合并区域首单元格的值,如果不在则继续判断下一个合并区域。如果不在任何一个合并区域内,则是非合并单元格
相关标签: POI