java - Java - 使用 POI 过滤 Excel 文件的行
问题描述
我有一个包含很多行(超过 60,000 行)的 Excel 文件,我想对它们应用过滤器,以便只读取我正在寻找的行。
我在 Java 中使用 POI 库,但我没有找到如何过滤值。
例如,在我的 Excel 文件中有以下数据:
First name | Last name | Age
-----------+-----------+----
Jhon | Doe | 25
Foo | Bar | 20
Aaa | Doe | 22
我如何选择姓氏等于的每一行Doe
?
到目前为止,这是我的代码:
public void parseExcelFile(XSSFWorkbook myExcelFile) {
XSSFSheet worksheet = myExcelFile.getSheetAt(1);
// Cell range to filter
CellRangeAddress data = new CellRangeAddress(
1,
worksheet.getLastRowNum(),
0,
worksheet.getRow(0).getPhysicalNumberOfCells());
worksheet.setAutoFilter(data);
}
我尝试使用,AutoFilter
但我不知道它是如何工作的。
我正在寻找一个看起来像这样的功能:
Filter filter = new Filter();
filter.setRange(myRange);
filter.addFilter(
0, // The column index
"Doe" // The value that I'm searching for
)
filter.apply()
这纯粹是假设的代码。
感谢您的帮助 !
解决方案
如果您的问题是如何AutoFilter
为姓氏设置标准“Doe”,那么这只能使用底层的低级ooxml-schemas
类来实现。XSSFAutoFilter
直到现在都没用。直到现在它还没有提供任何方法。
使用您的示例数据完成示例:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAutoFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFilterColumn;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFilters;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomFilters;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFilterOperator;
import java.io.FileOutputStream;
class AutoFilterSetTest {
private static void setCellData(Sheet sheet) {
Object[][] data = new Object[][] {
new Object[] {"First name", "Last name", "Age"},
new Object[] {"John", "Doe", 25},
new Object[] {"Foo", "Bar", 20},
new Object[] {"Jane", "Doe", 22},
new Object[] {"Ruth", "Moss", 42},
new Object[] {"Manuel", "Doe", 32},
new Object[] {"Axel", "Richter", 56},
};
Row row = null;
Cell cell = null;
int r = 0;
int c = 0;
for (Object[] dataRow : data) {
row = sheet.createRow(r);
c = 0;
for (Object dataValue : dataRow) {
cell = row.createCell(c);
if (dataValue instanceof String) {
cell.setCellValue((String)dataValue);
} else if (dataValue instanceof Number) {
cell.setCellValue(((Number)dataValue).doubleValue());
}
c++;
}
r++;
}
}
private static void setCriteriaFilter(XSSFSheet sheet, int colId, int firstRow, int lastRow, String[] criteria) throws Exception {
CTAutoFilter ctAutoFilter = sheet.getCTWorksheet().getAutoFilter();
CTFilterColumn ctFilterColumn = null;
for (CTFilterColumn filterColumn : ctAutoFilter.getFilterColumnList()) {
if (filterColumn.getColId() == colId) ctFilterColumn = filterColumn;
}
if (ctFilterColumn == null) ctFilterColumn = ctAutoFilter.addNewFilterColumn();
ctFilterColumn.setColId(colId);
if (ctFilterColumn.isSetFilters()) ctFilterColumn.unsetFilters();
CTFilters ctFilters = ctFilterColumn.addNewFilters();
for (int i = 0; i < criteria.length; i++) {
ctFilters.addNewFilter().setVal(criteria[i]);
}
//hiding the rows not matching the criterias
DataFormatter dataformatter = new DataFormatter();
for (int r = firstRow; r <= lastRow; r++) {
XSSFRow row = sheet.getRow(r);
boolean hidden = true;
for (int i = 0; i < criteria.length; i++) {
String cellValue = dataformatter.formatCellValue(row.getCell(colId));
if (criteria[i].equals(cellValue)) hidden = false;
}
if (hidden) {
row.getCTRow().setHidden(hidden);
} else {
if (row.getCTRow().getHidden()) row.getCTRow().unsetHidden();
}
}
}
public static void main(String[] args) throws Exception {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
//create rows of data
setCellData(sheet);
for (int c = 0; c < 2; c++) sheet.autoSizeColumn(c);
int lastRow = sheet.getLastRowNum();
XSSFAutoFilter autofilter = sheet.setAutoFilter(new CellRangeAddress(0, lastRow, 0, 2));
//XSSFAutoFilter is useless until now
//set filter criteria
setCriteriaFilter(sheet, 1, 1, lastRow, new String[]{"Doe"});
//get only visible rows after filtering
XSSFRow row = null;
for (int r = 1; r <= lastRow; r++) {
row = sheet.getRow(r);
if (row.getCTRow().getHidden()) continue;
for (int c = 0; c < 3; c++) {
System.out.print(row.getCell(c) + "\t");
}
System.out.println();
}
FileOutputStream out = new FileOutputStream("AutoFilterSetTest.xlsx");
wb.write(out);
out.close();
wb.close();
}
}
它打印:
John Doe 25.0
Jane Doe 22.0
Manuel Doe 32.0
结果AutoFilterSetTest.xlsx
如下:
推荐阅读
- android - Android RecyclerView ViewHolder OnClickListener 仅在单击项目边缘时工作
- vba - 我想从工作表“Prime Data”上的 A 列复制所有行,并使用代码粘贴到工作表“Pime - Tracking”上的 A 列
- dart - 在所有页面 Flutter 中持久化 AppBar Drawer
- php - 无法使用 AngularJS 和 PHP 发布
- vba - 基于两个单元格的唯一列表
- ruby - 获取标题标签后的内容(Ruby)
- c++ - 唯一命名对象表
- r - 润滑以 0 开头的日期的日期解析
- command-line - 如何在 cmd 中定向到我的 .cmd 所在的文件夹
- javascript - Angular 6:内部属性绑定 [innerHtml]