下午好的专家有问题,我需要按列名而不是索引来读取整个excel文件,例如:
Column1 | Column2 | Column3
data1 data 2 data 3
POI允许我通过为getColumnIndex()
返回的方法Column1 = 0 , Column2= 1 etc,
来读取列索引,但我需要按列名Column1
,Column2
等进行读取,
有没有办法做到这一点??
我需要按列名读取行和列的所有字段。 附上我读过我文件的代码:
更新代码:
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class example {
DataFormatter fmt = new DataFormatter();
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws FileNotFoundException, IOException {
example softMarti = new example();
FileInputStream file = new FileInputStream(new File("C:archive.xlsx"));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
int rowIndex = row.getRowNum();
if (rowIndex < 1) {
continue;
}
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
int columnIndex = cell.getColumnIndex();
if (columnIndex != 0 && columnIndex != 1 && columnIndex != 4) {
continue;
}
String columnName = "";
switch (columnIndex) {
case 0:
columnName = "column1";
break;
case 1:
columnName = "column2";
break;
case 4:
columnName = "column 4";
break;
}
String value = example.getValue(cell);
boolean valid = example.isValid(columnIndex, value);
if (valid) {
continue;
}
System.out.print(columnName + rowIndex);
System.out.println(" -> " + value);
}
}
// TODO code application logic here
}
private String getValue(Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
return null;
case Cell.CELL_TYPE_BOOLEAN:
return "CELL_TYPE_BOOLEAN";
case Cell.CELL_TYPE_ERROR:
return "CELL_TYPE_ERROR";
case Cell.CELL_TYPE_FORMULA:
return "CELL_TYPE_FORMULA";
case Cell.CELL_TYPE_NUMERIC:
return fmt.formatCellValue(cell);
case Cell.CELL_TYPE_STRING:
return cell.getStringCellValue();
default:
return "none";
}
}
boolean isValid(int column, String value) {
if (value == null) {
return false;
}
String pattern = "";
switch (column) {
case 0:
pattern = "[A-Za-z0-9_\\- ]{1,20}";
break;
case 1:
pattern = "[A-Za-z0-9_\\- ]{1,80}";
break;
case 4:
pattern = "[0-9]{1,8}";
break;
}
Pattern pat = Pattern.compile(pattern);
Matcher mat = pat.matcher(value);
return mat.matches();
}
}
此代码有效,但我需要验证列名,因为我的项目列可能会改变位置,这是我的目标
答案 0 :(得分:5)
为什么不读取第一行(0)单元格值(0-n)(也就是列名称)并将(columnName,columnIndex)放入String / int的映射中。然后,您可以按名称引用列索引。
以下是一个例子:
Map<String, Integer> map = new HashMap<String,Integer>(); //Create map
HSSFRow row = sheet.getRow(0); //Get first row
//following is boilerplate from the java doc
short minColIx = row.getFirstCellNum(); //get the first column index for a row
short maxColIx = row.getLastCellNum(); //get the last column index for a row
for(short colIx=minColIx; colIx<maxColIx; colIx++) { //loop from first to last index
HSSFCell cell = row.getCell(colIx); //get the cell
map.put(cell.getStringCellValue(),cell.getColumnIndex()) //add the cell contents (name of column) and cell index to the map
}
在此之后你将拥有columnName ---&gt;的地图。指数。然后你可以这样做:
int idx = map.get("ColumnName");
....你可以在row.getCell(idx)中使用它来获取所有其他行中的单元格。
在代码中阅读以下评论。除此之外,我无法帮助你。您需要阅读文档并弄清楚如何操作。
Workbook workbook = WorkbookFactory.create(new FileInputStream("C:\\file.xlsx"));
Sheet sheet = workbook.getSheetAt(0);
totalRows = sheet.getPhysicalNumberOfRows();
Map<String, Integer> map = new HashMap<String,Integer>(); //Create map
HSSFRow row = sheet.getRow(0); //Get first row
//following is boilerplate from the java doc
short minColIx = row.getFirstCellNum(); //get the first column index for a row
short maxColIx = row.getLastCellNum(); //get the last column index for a row
for(short colIx=minColIx; colIx<maxColIx; colIx++) { //loop from first to last index
HSSFCell cell = row.getCell(colIx); //get the cell
map.put(cell.getStringCellValue(),cell.getColumnIndex()) //add the cell contents (name of column) and cell index to the map
}
List<ReportRow> listOfDataFromReport = new ArrayList<ReportRow>();
for(int x = 1; x<=totalRows; x++){
ReportRow rr = new ReportRow(); //Data structure to hold the data from the xls file.
HSSFRow dataRow = sheet.getRow(x); //get row 1 to row n (rows containing data)
int idxForColumn1 = map.get("Column1"); //get the column index for the column with header name = "Column1"
int idxForColumn2 = map.get("Column2"); //get the column index for the column with header name = "Column2"
int idxForColumn3 = map.get("Column3"); //get the column index for the column with header name = "Column3"
HSSFCell cell1 = dataRow.getCell(idxForColumn1) //Get the cells for each of the indexes
HSSFCell cell2 = dataRow.getCell(idxForColumn2)
HSSFCell cell3 = dataRow.getCell(idxForColumn3)
//NOTE THAT YOU HAVE TO KNOW THE DATA TYPES OF THE DATA YOU'RE EXTRACTING.
//FOR EXAMPLE I DON'T THINK YOU CAN USE cell.getStringCellValue IF YOU'RE TRYING TO GET A NUMBER
rr.setColumn1(cell1.getStringCellValue()); //Get the values out of those cells and put them into the report row object
rr.setColumn2(cell2.getStringCellValue());
rr.setColumn3(cell3.getStringCellValue());
listOfDataFromReport.add(rr);
}
//Now you have a list of report rows
for(int j = 0; j< listOfDataFromReport.size();j++){
System.out.println("Column 1 Value: " + listOfDataFromReport.get(j).getColumn1())
//etc...
}
//This class holds the values from the xls file. You may not need it
// I have no idea what you're doing with the data. If you simply wanted to
//print the data to console you wouldn't need it.
public static class ReportRow{
private String column1;
private String column2;
private String column3;
public String getColumn1(){
return this.column1;
}
public void setColumn1(String column1){
this.column1 = column1;
}
public String getColumn2(){
return this.column2;
}
public void setColumn2(String column2){
this.column2 = column2;
}
public String getColumn3(){
return this.column3;
}
public void setColumn3(String column3){
this.column3 = column3;
}
}
答案 1 :(得分:1)
我写了一个方法
public static int columnName(String a) throws EncryptedDocumentException, InvalidFormatException, IOException {
int coefficient = 0;
String excelFilePath = ConfigurationReader.getProperty("pathToYourFile"); // or specify the path directly
FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
Workbook wb = WorkbookFactory.create(inputStream);
Sheet sh = wb.getSheet("Sheet1");
Row row = sh.getRow(0);
int cellNum = row.getPhysicalNumberOfCells();
for (int i = 0; i < cellNum; i++) {
if ((row.getCell(i).toString()).equals(a)) {
coefficient = i;
}
}
return coefficient;
}
然后在我的代码中调用它:
Cell anyCellName = row.getCell(columnName("NameOfColumnInMyExcell"));
并使用任何列名进行此操作。现在,我可以按任何顺序移动列,并且代码可以正常工作。