如何在Excel(xlsx)中使用Apache POI读取与特定列名相关的值。
列名是Excel表的第一行。 value是以Y作为单元格值的行。
我的输入只是列名, 我需要列名称和行的值,其值为#34; Y"
这里我输入列名为"姓名" ,它应该回报价值"何塞" 而且"年龄"它应该返回23
我尝试过发现两个不同循环系统的代码,但是出现了一些错误
public static void main(String[] args) throws Exception {
File file = new File("D:\\xcel.xlsx");
FileInputStream inputStream = new FileInputStream(file);
Workbook wb = new XSSFWorkbook(inputStream);
Sheet sh = wb.getSheet("Sheet1");
// Find the Column number Which has column name and row number 0
Row row1 = sh.getRow(0);
int colNum = -1;
for (int i = 0 ;i<=row1.getLastCellNum();i++){
Cell cell1 = row1.getCell(i,Row.CREATE_NULL_AS_BLANK);
String cellValue1 = cell1.getStringCellValue();
if ("Employee".equals(cellValue1)){
colNum = i ;
break;}
}
// Find the Row number Which is "Y" and column number 1
int rowNum = -1;
for (int j = 0 ;j<=sh.getLastRowNum()+1;j++){
Row row2 = sh.getRow(j);
Cell cell2 = row2.getCell(1,Row.CREATE_NULL_AS_BLANK);
String cellValue2 = cell2.getStringCellValue();
if ("Y".equals(cellValue2))
{ rowNum = j ;
break;}
}
Row r = sh.getRow(rowNum);
String val = r.getCell(colNum).getStringCellValue();
System.out.println("Row number is "+rowNum);
System.out.println("Last row number :"+sh.getLastRowNum());
System.out.println("Column number is "+colNum);
System.out.println("Last Column number :"+sh.getRow(0).getLastCellNum());
System.out.println("Value is "+val);
}
当我运行上面的代码时,即使在它之前有空白单元格,我也会得到列号,
但是对于行,如果在它之前存在空白单元格,我会在线程&#34; main&#34;中得到错误异常。显示java.lang.NullPointerException 但如果没有黑细胞,它就能正常工作。
再次在下面的代码中,我没有收到任何错误
但如果我的列名存在于最后一个单元格中,那么最后一个单元格编号和我的列编号应该相同,但是我的列编号比最后一个单元格编号小一个。
但是对于行号,它很好,我得到相同的数字。
此问题也适用于第一个代码
public static void main(String[] args) throws Exception {
File file = new File("D:\\xcel.xlsx");
FileInputStream inputStream = new FileInputStream(file);
Workbook wb = new XSSFWorkbook(inputStream);
Sheet sh = wb.getSheet("Sheet1");
// Find the Column number Which has column name and row number 0
Row row1 = sh.getRow(0);
int colNum = -1;
for (Cell cell : row1) {
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
if (cell.getRichStringCellValue().getString().trim().equals("Employee")) {
colNum = cell.getColumnIndex(); }
}
}
// Find the Row number Which is "Y" and column number 1
int rowNum = -1;
for (Row row : sh) {
for (Cell cell : row) {
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
if (cell.getRichStringCellValue().getString().trim().equals("Y")) {
rowNum = row.getRowNum(); }
}
}
}
// Get the required value
Row r = sh.getRow(rowNum);
String val = r.getCell(colNum).getStringCellValue();
System.out.println("Row number is "+rowNum);
System.out.println("Last row number :"+sh.getLastRowNum());
System.out.println("Column number is "+colNum);
System.out.println("Last Column number :"+sh.getRow(0).getLastCellNum());
System.out.println("Value is "+val);
答案 0 :(得分:0)
Apache POI不支持此类事情。
您可能需要将EXCEL文件读取为您自己写入的抽象结构。
我建议使用包含标题和内容的文档模型。
如果您的目的只是按列名收集值,并且有一些数据冗余,则可以将每个值存储为{column name:row value}的映射条目,列在所有行的列表中。
拥有这样的结构时,您可以轻松地按列值进行搜索。
例如:
import java.util.ArrayList;
import java.util.List;
public class Document {
private List<String> headers;
private List<DataRow> contents;
public Document(List<String> headers, List<DataRow> contents) {
this.headers = headers;
this.contents = contents;
}
public List<DataRow> findAllWhere(String column, String value) {
List<DataRow> result = new ArrayList<>();
for (DataRow content : contents) {
if (content.get(column).equals(value)) {
result.add(content);
}
}
return result;
}
public List<DataRow> getContents() {
return contents;
}
public void setContents(List<DataRow> contents) {
this.contents = contents;
}
public List<String> getHeaders() {
return headers;
}
public void setHeaders(List<String> headers) {
this.headers = headers;
}
@Override
public String toString() {
return "Document{" +
"headers=" + headers +
", contents=" + contents +
'}';
}
}
对于行,我们可以这样:
import java.util.HashMap;
import java.util.Map;
public class DataRow {
private Map<String, String> values = new HashMap<>();
private Integer index;
public String put(String columnName, String value) {
return values.put(columnName, value);
}
public String get(String columnName) {
return values.get(columnName);
}
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
@Override
public String toString() {
return "DataRow{" +
"values=" + values +
", index=" + index +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DataRow dataRow = (DataRow) o;
if (values != null ? !values.equals(dataRow.values) : dataRow.values != null) return false;
return !(index != null ? !index.equals(dataRow.index) : dataRow.index != null);
}
@Override
public int hashCode() {
int result = values != null ? values.hashCode() : 0;
result = 31 * result + (index != null ? index.hashCode() : 0);
return result;
}
}
如何解析它的示例:
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Parser {
private InputStream stream;
public Parser(InputStream stream) {
this.stream = stream;
}
public Document parse() {
try {
Workbook wb = WorkbookFactory.create(stream);
//TODO better sheet searching
Sheet sheet = wb.getSheetAt(0);
Iterator<Row> rows = sheet.rowIterator();
List<String> headers = new ArrayList<>();
if (rows.hasNext()) {
Row row = rows.next();
for (Cell cell : row) {
headers.add(cell.getStringCellValue());
}
}
List<DataRow> contents = new ArrayList<>();
while (rows.hasNext()) {
Row row = rows.next();
DataRow dataRow = new DataRow();
dataRow.setIndex(row.getRowNum());
for (Cell cell : row) {
//TODO safeguard for header resolving, cell column index might be out of bound of header array
dataRow.put(
headers.get(cell.getColumnIndex()),
cell.getStringCellValue()
);
}
contents.add(dataRow);
}
return new Document(headers, contents);
} catch (IOException | InvalidFormatException e) {
throw new RuntimeException(e);
}
}
}
示例使用方法:
Parser parser = new Parser(getClass().getResourceAsStream("resource.xlsx"));
List<DataRow> data = parser.parse().findAllWhere("FLAG", "Y");
完整模拟可用here
这是你在找什么? 我必须警告你,每次你需要搜索整个excel时,这不是一个好主意。
public static String findFirstExecute(String excelPath, String sheetName, String columnName) {
return findFirstValue(excelPath, sheetName, columnName, "Execute", "Y");
}
public static String findFirstValue(String excelPath, String sheetName, String columnName, String filterColumnName, String filterColumnValue) {
try {
Workbook wb = WorkbookFactory.create(new FileInputStream(new File(excelPath)));
Sheet sheet = wb.getSheet(sheetName);
Iterator<Row> rows = sheet.rowIterator();
Map<String, Integer> headers = new HashMap<>();
if (rows.hasNext()) {
Row row = rows.next();
for (Cell cell : row) {
headers.put(cell.getStringCellValue(), cell.getColumnIndex());
}
}
while (rows.hasNext()) {
Row row = rows.next();
String executeValue = row.getCell(headers.get(filterColumnName)).getStringCellValue();
if (executeValue.equals(filterColumnValue)) {
return row.getCell(headers.get(columnName)).getStringCellValue();
}
}
return null;
} catch (IOException | InvalidFormatException e) {
throw new RuntimeException(e);
}
}