我想通过单元测试来验证是否已定义组和当前的崩溃状态。如果我无法通过工作表检查列,则可以测试每个单元格的状态。我没有看到任何类似isGroup()isGroupCollapsed()的方法。
如果行或列的大纲级别大于0,则存在一个组。如果隐藏了所有组成员(行或列),则该组将折叠。
对于行,可以确定行的大纲级别和隐藏状态。当前apache poi 4.1.2
通过方法Row.getOutlineLevel和Row.getZeroHeight来提供。如果某行的大纲级别大于0,则它属于具有该大纲级别的组。该组从具有不低于该行的大纲级别的大纲级别的最小的前一行开始。该组在最大后继行结束,该行的大纲级别不低于该行的大纲级别。并且,如果隐藏了组的开始行和组的结束行之间的所有连续行,则整个组将被隐藏并折叠。
因此,我们可以遍历工作表中的所有行,并具有可以从一行中收集行组信息的方法。在以下代码中,这是方法
int findStartOfRowOutlineGroup(Row row)
和
int findEndOfRowOutlineGroup(Row row)
和
boolean getIsWholeRowGroupHidden(Sheet sheet, int startOfRowOutlineGroup, int endOfRowOutlineGroup)
对于列,可以从工作表中确定列的轮廓级别和隐藏状态。当前apache poi 4.1.2
方法通过Sheet.getColumnOutlineLevel和Sheet.isColumnHidden提供。如果列的大纲级别大于0,则它属于具有该大纲级别的组。该组从具有不低于该列的大纲级别的大纲级别的最小的前一列开始。该组在最大后继列上结束,该列的大纲级别不低于该列的大纲级别。并且,如果隐藏了组的开始列和组的结束列之间的所有连续列,则整个组将被隐藏并折叠。
因此,我们可以遍历工作表中的所有列,并拥有可以从工作表中收集col-group-信息的方法。在以下代码中,这是方法
int findStartOfColOutlineGroup(Sheet sheet, int col)
和
int findEndOfColOutlineGroup(Sheet sheet, int col)
和
boolean getIsWholeColGroupHidden(Sheet sheet, int startOfColOutlineGroup, int endOfColOutlineGroup)
完整的例子:
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
public class ExcelColumnGroupsRowGroups {
static String getRowGroupInfos(Row row) {
int outlineLevel = row.getOutlineLevel();
String result = "Row "+(row.getRowNum()+1)+" belongs to no group.";
if (outlineLevel > 0) {
int startOfRowOutlineGroup = findStartOfRowOutlineGroup(row); //0-based
int endOfRowOutlineGroup = findEndOfRowOutlineGroup(row); //0-based
boolean isRowHidden = row.getZeroHeight();
boolean isWholeGroupHidden = getIsWholeRowGroupHidden(row.getSheet(), startOfRowOutlineGroup, endOfRowOutlineGroup);
result = "Row "+(row.getRowNum()+1)+" belongs to group having outline level:"+outlineLevel+". "
+"Group starts at row "+(startOfRowOutlineGroup+1)+" and ends at row "+(endOfRowOutlineGroup+1)+". "
+"Row "+(row.getRowNum()+1)+" is "+((isRowHidden)?"hidden":"not hidden")+". "
+"Whole group is "+((isWholeGroupHidden)?"hidden":"not hidden")+". ";
}
return result;
}
static int findStartOfRowOutlineGroup(Row row) { //0-based
int outlineLevel = row.getOutlineLevel();
int r = row.getRowNum();
if (outlineLevel > 0) {
while (r >= 0) {
row = row.getSheet().getRow(r);
if (row == null) break;
int prevOutlineLevel = row.getOutlineLevel();
if (prevOutlineLevel < outlineLevel) break;
r--;
}
}
return r+1;
}
static int findEndOfRowOutlineGroup(Row row) { //0-based
int outlineLevel = row.getOutlineLevel();
int r = row.getRowNum();
if (outlineLevel > 0) {
while (r <= row.getSheet().getLastRowNum()) {
row = row.getSheet().getRow(r);
if (row == null) break;
int prevOutlineLevel = row.getOutlineLevel();
if (prevOutlineLevel < outlineLevel) break;
r++;
}
}
return r-1;
}
static boolean getIsWholeRowGroupHidden(Sheet sheet, int startOfRowOutlineGroup, int endOfRowOutlineGroup) {
boolean result = true;
Row row;
for (int r = startOfRowOutlineGroup; r <= endOfRowOutlineGroup; r++) {
row = sheet.getRow(r);
if (row == null) {
result = false;
break;
} else if (!row.getZeroHeight()) {
result = false;
break;
}
}
return result;
}
static String getColGroupInfos(Sheet sheet, int c) {
int outlineLevel = sheet.getColumnOutlineLevel(c);
String result = "Col "+(c+1)+" belongs to no group.";
if (outlineLevel > 0) {
int startOfColOutlineGroup = findStartOfColOutlineGroup(sheet, c); //0-based
int endOfColOutlineGroup = findEndOfColOutlineGroup(sheet, c); //0-based
boolean isColHidden = sheet.isColumnHidden(c);
boolean isWholeGroupHidden = getIsWholeColGroupHidden(sheet, startOfColOutlineGroup, endOfColOutlineGroup);
result = "Col "+(c+1)+" belongs to group having outline level:"+outlineLevel+". "
+"Group starts at col "+(startOfColOutlineGroup+1)+" and ends at col "+(endOfColOutlineGroup+1)+". "
+"Col "+(c+1)+" is "+((isColHidden)?"hidden":"not hidden")+". "
+"Whole group is "+((isWholeGroupHidden)?"hidden":"not hidden")+". ";
}
return result;
}
static int findStartOfColOutlineGroup(Sheet sheet, int col) { //0-based
int outlineLevel = sheet.getColumnOutlineLevel(col);
int c = col;
if (outlineLevel > 0) {
while (c >= 0) {
int prevOutlineLevel = sheet.getColumnOutlineLevel(c);
if (prevOutlineLevel < outlineLevel) break;
c--;
}
}
return c+1;
}
static int findEndOfColOutlineGroup(Sheet sheet, int col) { //0-based
int outlineLevel = sheet.getColumnOutlineLevel(col);
int c = col;
if (outlineLevel > 0) {
while (c <= sheet.getWorkbook().getSpreadsheetVersion().getLastColumnIndex()) {
int prevOutlineLevel = sheet.getColumnOutlineLevel(c);
if (prevOutlineLevel < outlineLevel) break;
c++;
}
}
return c-1;
}
static boolean getIsWholeColGroupHidden(Sheet sheet, int startOfColOutlineGroup, int endOfColOutlineGroup) {
boolean result = true;
for (int c = startOfColOutlineGroup; c <= endOfColOutlineGroup; c++) {
if (!sheet.isColumnHidden(c)) {
result = false;
break;
}
}
return result;
}
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelSheetGroupedColsAndRows.xlsx"));
//Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelSheetGroupedColsAndRows.xls"));
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
String rowGroupInfos = getRowGroupInfos(row);
System.out.println(rowGroupInfos);
}
for (int c = 0; c <= workbook.getSpreadsheetVersion().getLastColumnIndex(); c++) {
if (sheet.getColumnOutlineLevel(c) > 0) {
String colGroupInfos = getColGroupInfos(sheet, c);
System.out.println(colGroupInfos);
}
}
workbook.close();
}
}
我碰巧遇到了大纲级别的技巧,并且正在探索与隐藏价值的关系。您证实了我的想法,并提供了很多好东西。作为TDD,我发现POI允许设置值常常令人沮丧,但没有明显的方法来检索状态。希望他们有一天能到达那里。
@Bill Turner:好吧,我怀疑是否有可能追赶几十年
Microsoft
的Excel
发展,该发展仅具有Office Open XML
(*.xlsx
)的公共文件描述,而只有二进制文件系统BIFF
(*.xls
)的反向工程结果。至少,如果甚至不遵循Microsoft
API
s而是尝试实现自己的对象和方法。但是,可能遵循Microsoft
API
s甚至Libreoffice
或OpenOffice
API
s会有法律问题。考虑到所有这些,apache poi
都处于非常好的状态。