Java 如何使用POI库从excel中读取筛选行
我正在使用java代码中的POI库读取excel文件。到目前为止还不错。但现在我有一个要求。excel文件包含许多记录(例如1000行)。它还有列标题(第1行)。现在我正在对它进行excel过滤。假设我有一个'year'列,并且我正在筛选year=2019的所有行。我有15排。 问题:我只想在java代码中处理这15行。poi库中是否有任何方法或方法可以知道正在读取的行是否已过滤(另一种方法,即未过滤)。 谢谢 我已经有工作代码,但现在我正在寻找如何只读过滤行。除了在图书馆和论坛中搜索之外,还没有什么新的尝试 下面的代码在一个方法中。我不习惯使用stackoverflow设置格式,所以请忽略任何格式问题Java 如何使用POI库从excel中读取筛选行,java,apache-poi,Java,Apache Poi,我正在使用java代码中的POI库读取excel文件。到目前为止还不错。但现在我有一个要求。excel文件包含许多记录(例如1000行)。它还有列标题(第1行)。现在我正在对它进行excel过滤。假设我有一个'year'列,并且我正在筛选year=2019的所有行。我有15排。 问题:我只想在java代码中处理这15行。poi库中是否有任何方法或方法可以知道正在读取的行是否已过滤(另一种方法,即未过滤)。 谢谢 我已经有工作代码,但现在我正在寻找如何只读过滤行。除了在图书馆和论坛中搜索之外,还没
// For storing data into CSV files
StringBuffer data = new StringBuffer();
try {
SimpleDateFormat dtFormat = new SimpleDateFormat(CommonConstants.YYYY_MM_DD); // "yyyy-MM-dd"
String doubleQuotes = "\"";
FileOutputStream fos = new FileOutputStream(outputFile);
// Get the workbook object for XLSX file
XSSFWorkbook wBook = new XSSFWorkbook(new FileInputStream(inputFile));
wBook.setMissingCellPolicy(Row.RETURN_BLANK_AS_NULL);
// Get first sheet from the workbook
//XSSFSheet sheet = wBook.getSheetAt(0);
XSSFSheet sheet = wBook.getSheet(CommonConstants.METADATA_WORKSHEET);
//Row row;
//Cell cell;
// Iterate through each rows from first sheet
int rows = sheet.getLastRowNum();
int totalRows = 0;
int colTitelNumber = 0;
Row firstRowRecord = sheet.getRow(1);
for (int cn = 0; cn < firstRowRecord.getLastCellNum(); cn++) {
Cell cellObj = firstRowRecord.getCell(cn);
if(cellObj != null) {
String str = cellObj.toString();
if(CommonConstants.COLUMN_TITEL.equalsIgnoreCase(str)) {
colTitelNumber = cn;
break;
}
}
}
// Start with row Number 1. We don't need 0th number row as it is for Humans to read but not required for processing.
for (int rowNumber = 1; rowNumber <= rows; rowNumber++) {
StringBuffer rowData = new StringBuffer();
boolean skipRow = false;
Row rowRecord = sheet.getRow(rowNumber);
if (rowRecord == null) {
LOG.error("Empty/Null record found");
} else {
for (int cn = 0; cn < rowRecord.getLastCellNum(); cn++) {
Cell cellObj = rowRecord.getCell(cn);
if(cellObj == null) {
if(cn == colTitelNumber) {
skipRow = true;
break; // The first column cell value is empty/null. Which means Titel column cell doesn't have value so don't add this row in csv.
}
rowData.append(CommonConstants.CSV_SEPARTOR);
continue;
}
switch (cellObj.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
rowData.append(cellObj.getBooleanCellValue() + CommonConstants.CSV_SEPARTOR);
//LOG.error("Boolean:" + cellObj.getBooleanCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cellObj)) {
Date date = cellObj.getDateCellValue();
rowData.append(dtFormat.format(date).toString() + CommonConstants.CSV_SEPARTOR);
//LOG.error("Date:" + cellObj.getDateCellValue());
} else {
rowData.append(cellObj.getNumericCellValue() + CommonConstants.CSV_SEPARTOR);
//LOG.error("Numeric:" + cellObj.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_STRING:
String cellValue = cellObj.getStringCellValue();
// If string contains double quotes then replace it with pair of double quotes.
cellValue = cellValue.replaceAll(doubleQuotes, doubleQuotes + doubleQuotes);
// If string contains comma then surround the string with double quotes.
rowData.append(doubleQuotes + cellValue + doubleQuotes + CommonConstants.CSV_SEPARTOR);
//LOG.error("String:" + cellObj.getStringCellValue());
break;
case Cell.CELL_TYPE_BLANK:
rowData.append("" + CommonConstants.CSV_SEPARTOR);
//LOG.error("Blank:" + cellObj.toString());
break;
default:
rowData.append(cellObj + CommonConstants.CSV_SEPARTOR);
}
}
if(!skipRow) {
rowData.append("\r\n");
data.append(rowData); // Appending one entire row to main data string buffer.
totalRows++;
}
}
}
pTransferObj.put(CommonConstants.TOTAL_ROWS, (totalRows));
fos.write(data.toString().getBytes());
fos.close();
wBook.close();
} catch (Exception ex) {
LOG.error("Exception Caught while generating CSV file", ex);
}
//用于将数据存储到CSV文件中
StringBuffer数据=新的StringBuffer();
试一试{
SimpleDataFormat dtFormat=新的SimpleDataFormat(CommonConstants.YYYY_-MM_-DD);/“yyy-MM-DD”
字符串双引号=“\”;
FileOutputStream fos=新的FileOutputStream(outputFile);
//获取XLSX文件的工作簿对象
XSSF工作簿wBook=新XSSF工作簿(新文件InputStream(inputFile));
wBook.setMissingCellPolicy(行。返回为空);
//从工作簿中获取第一张工作表
//XSSFSheet sheet=wBook.getSheetAt(0);
XSSFSheet sheet=wBook.getSheet(CommonConstants.METADATA_工作表);
//行行;
//细胞;
//从第一张图纸开始遍历每行
int rows=sheet.getLastRowNum();
int totalRows=0;
int colTitelNumber=0;
Row firstRowRecord=sheet.getRow(1);
对于(int cn=0;cn 对于(int rowNumber=1;rowNumber,您必须使用Apache Poi库中提供的自动过滤器,并且您已经设置了冻结
XSSFSheet sheet = wBook.getSheet(CommonConstants.METADATA_WORKSHEET);
sheet.setAutoFilter(new CellRangeAddress(0, 0, 0, numColumns));
sheet.createFreezePane(0, 1);
您必须使用ApachePOI库中提供的自动过滤器,并且您已经设置了冻结
XSSFSheet sheet = wBook.getSheet(CommonConstants.METADATA_WORKSHEET);
sheet.setAutoFilter(new CellRangeAddress(0, 0, 0, numColumns));
sheet.createFreezePane(0, 1);
所有在工作表中不可见的行的高度都为零。因此,如果只需要读取可见行,可以通过检查
范例
工作表:
代码:
结果:
F1 F2 F3 F4
V2 2 2-Mai FALSE
V4 4 4-Mai FALSE
V2 6 6-Mai FALSE
V4 8 8-Mai FALSE
所有在工作表中不可见的行的高度都为零。因此,如果只需要读取可见行,可以通过检查
范例
工作表:
代码:
结果:
F1 F2 F3 F4
V2 2 2-Mai FALSE
V4 4 4-Mai FALSE
V2 6 6-Mai FALSE
V4 8 8-Mai FALSE
我必须重写一些钩子,并提出我自己的方法来合并隐藏行的过滤,以防止处理这些行。下面是代码片段。我的方法包括打开同一工作表的第二个副本,以便我可以查询正在处理的当前行,以查看它是否隐藏。上面的答案涉及到下面对其进行了扩展,以展示如何将其很好地整合到Spring batch excel框架中。一个缺点是,您必须打开同一文件的第二个副本,但我找不到方法(可能没有!)为了获得内部工作簿工作表,还有其他原因,因为org.springframework.batch.item.excel.poi.poiseheet
是包私有的(注意下面的语法是Groovy!!!):
/**
*生成一个读取器,该读取器知道如何以excel格式接收文件。
*/
私有POITEMReader createExcelReader(字符串文件路径){
文件f=新文件(文件路径)
POITEMReader=新POITEMReader()
reader.setRowMapper(新的PassThroughRowMapper())
Resource Resource=new DefaultResourceLoader().getResource(“文件:”+f.canonicalPath)
reader.setResource(资源)
reader.setRowSetFactory(新的VisibleRowsOnlyRowSetFactory(资源))
reader.open(新建ExecutionContext())
读者
}
...
//我重写的“钩子”注入了我的逻辑
静态类VisibleRowsOnlyRowSet扩展了DefaultRowSet{
工作簿
床单
VisibleRowsOnlyRowSet(最终工作表、最终行集元数据){
超级(工作表、元数据)
}
VisibleRowsOnlyRowSet(最终工作表、最终行集元数据、工作簿){
此(表、元数据)
this.workbook=工作簿
this.sheet=sheet
}
布尔下一步(){
布尔moreLeft=super.next()
如果(左){
行行=工作簿.getSheet(sheet.name).getRow(getCurrentRowIndex())
如果(行?.getZeroHeight()){
log.warn(“行$currentRow隐藏在输入excel工作表中,将从输出中忽略它。”)
currentRow.eachWithIndex{{,int i->
currentRow[i]=''
}
}
}
莫尔利特
}
}
静态类VisibleRowsOnlyRowSetFactory扩展了DefaultRowSetFactory{
工作簿
VisibleRowsOnlyRowSetFactory(资源){
this.workbook=WorkbookFactory.create(resource.inputStream)
}
行集创建(图纸){
新的VisibleRowsOnlyRowSet(工作表,super.create(工作表).元数据,工作簿)
}
}
我必须重写一些钩子,并提出我自己的方法来合并隐藏行的过滤,以防止处理这些行。下面是代码片段。我的方法包括打开同一工作表的第二个副本,以便我可以查询正在处理的当前行,看看它是否隐藏。上面的答案是:基于此,下面的exp