【问题标题】:How to convert my xlsx sheet to java object using Apache POI如何使用 Apache POI 将我的 xlsx 工作表转换为 java 对象
【发布时间】:2014-03-27 18:17:54
【问题描述】:

谁能建议我使用 Apache POI 将我的 xlsx 表转换为 java 对象。

eq,我的excel表格包含两列

  • emp_no emp_name
  • 01 和
  • 02 库马尔

还有我的java对象

Employee{
String empNo;
String empName; 
}

现在我想将我的 excel 工作表转换为 java 对象。 我在互联网上尝试过,但大多数教程都在讨论迭代每一行并将值分配给对象中的每个成员。 JAXB xml 解析器中是否有类似 Marshaller 和 UnMarshaller 的功能可以直接转换。

提前致谢。

【问题讨论】:

  • 请阅读How to Ask 并改进您的问题。如果您根本没有尝试过任何东西,那么这里不是索要代码的地方。
  • 嗨 Jonathan Drapeau,感谢您的重播,实际上我已经尝试了很多教程,所有教程都是关于将 java 对象转换为 excel 我看不到 excel 到 java 对象这就是我拥有的原因在这里问问题。
  • 你找到答案了吗?我想知道您是否找到了映射器或如何从 Apache POI Row 映射到对象?
  • 有一个名为Poiji 在内部使用 Apache POI 的框架

标签: java excel apache apache-poi


【解决方案1】:

对于给定的场景,我假设工作表的每一行都代表一个员工,其中第一列保留员工编号,第二列保留员工姓名。所以你可以使用以下内容:

Employee{
  String empNo;
  String empName; 
}

创建一个分配员工信息的方法

assignEmployee(Row row){
    empNo = row.getCell(0).toString();
    empName = row.getCell(1).toString();
}

或者,如果你愿意,你可以为它创建一个构造函数。

现在您只需要遍历每一行即可使用上述方法获取/使用信息。

Employee emp = new Employee();
Iterator<Row> itr = sheet.iterator();
    while(itr.hasNext()){
       Row row = itr.next();
       emp.assignEmployee(row);
      //  enter code here for the rest operation
}

【讨论】:

  • 感谢您的回复而不是迭代每一行有什么方法可以转换,例如 JAXB 我们有一个叫做 Unmarshaller 的概念,marshaller 有助于将对象转换为 xml 和 xml 到对象。有没有Apache POI 中可用的功能
  • 如果我想避免遍历 excel 数据之间的空行怎么办?
  • 您也可以使用 row.cellIterator() 遍历特定行的单元格
【解决方案2】:

刚找到两个库:

希望对某人有所帮助。

【讨论】:

【解决方案3】:

使用 Apache POI 在内部尝试这个库,以便从 excel 转换为 POJO。: Poji

【讨论】:

    【解决方案4】:

    我正在使用 POI,我正在上传一个简单的程序。希望这会帮助你。

    注意:记得更改文件路径。

    罐子详细信息:dom4j-1.6.1.jar、poi-3.9.jar、poi-ooxml-3.9.jar、poi-ooxml-schemas-3.11.jar、xmlbeans-2.6.0.jar

    我在 Excel 表格中的数据:

    ID   NAME  LASTNAME 
    1.0  Ena   Rana 
    2.0  Meena Hanly 
    3.0  Tina  Mounce 
    4.0  Dina  Cobain 
    

    模型或 Pojo:NewEmployee.java

    public class NewEmployee {
         private Double id;
         private String firstName;
         private String lastName;
    
         public NewEmployee(){}
    
        public NewEmployee(Double id, String firstName, String lastName) {
            super();
            this.id = id;
            this.firstName = firstName;
            this.lastName = lastName;
        }
    
        public Double getId() {
            return id;
        }
    
        public void setId(Double id) {
            this.id = id;
        }
    
        public String getFirstName() {
            return firstName;
        }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }    
    }
    

    主要方法:ExcelToObject.java

    import java.io.File;
    import java.io.FileInputStream;
    import java.util.ArrayList;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    public class ExcelToObject {
    
        public static void main(String[] args) {
             try
              {
                  FileInputStream file = new FileInputStream(new File("/home/ohelig/eclipse/New Worksheet.xlsx"));
    
                  //Create Workbook instance holding reference to .xlsx file
                  XSSFWorkbook workbook = new XSSFWorkbook(file);
    
                  //Get first/desired sheet from the workbook
                  XSSFSheet sheet = workbook.getSheetAt(0);
    
                  ArrayList<NewEmployee> employeeList = new ArrayList<>();
        //I've Header and I'm ignoring header for that I've +1 in loop
                  for(int i=sheet.getFirstRowNum()+1;i<=sheet.getLastRowNum();i++){
                      NewEmployee e= new NewEmployee();
                      Row ro=sheet.getRow(i);
                      for(int j=ro.getFirstCellNum();j<=ro.getLastCellNum();j++){
                          Cell ce = ro.getCell(j);
                        if(j==0){  
                            //If you have Header in text It'll throw exception because it won't get NumericValue
                            e.setId(ce.getNumericCellValue());
                        }
                        if(j==1){
                            e.setFirstName(ce.getStringCellValue());
                        }
                        if(j==2){
                            e.setLastName(ce.getStringCellValue());
                        }    
                      }
                      employeeList.add(e);
                  }
                  for(NewEmployee emp: employeeList){
                      System.out.println("ID:"+emp.getId()+" firstName:"+emp.getFirstName());
                  }
                  file.close();
              } 
              catch (Exception e) 
              {
                  e.printStackTrace();
              }
          }
    }
    

    【讨论】:

      【解决方案5】:

      我有同样的问题,我知道通过标准(Apache POI)实现为什么要花费这么多时间,所以在搜索和环顾四周后,我找到了更好的原因(JXLS-Reader)

      首先使用/导入/包含库 jxls-reader

          <dependency>
              <groupId>org.jxls</groupId>
              <artifactId>jxls-reader</artifactId>
              <version>2.0.3</version>
          </dependency>
      

      然后创建一个由库使用的 XML 文件,用于列和您的对象属性之间的对应关系,在您的示例中,此 XML 将一个初始化列表作为参数,通过从 Excel 文件中提取的数据(员工对象)填充它,它看起来像:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <workbook>
          <worksheet idx="0">
              <section startRow="0" endRow="0" />
              <loop startRow="1" endRow="1" items="employeeList" var="employee" varType="com.department.Employee">
                  <section startRow="1" endRow="1">
                  <mapping row="1"  col="0">employee.empNo</mapping>
                  <mapping row="1"  col="1">employee.empName</mapping>
                  </section>
                  <loopbreakcondition>
                      <rowcheck offset="0">
                          <cellcheck offset="0"></cellcheck>
                      </rowcheck>
                  </loopbreakcondition>
              </loop>
          </worksheet>
      </workbook>
      

      然后在Java中,初始化Employees列表(解析结果会包含在其中),然后通过输入的Excel文件和XML映射调用JXLS阅读器,如下所示:

      package com.department;
      
      import java.io.BufferedInputStream;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.util.ArrayList;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
      
      import org.apache.commons.io.IOUtils;
      import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
      import org.jxls.reader.ReaderBuilder;
      import org.jxls.reader.ReaderConfig;
      import org.jxls.reader.XLSReader;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.xml.sax.SAXException;
      
      
      public class ExcelProcessor {
      
          private static Logger logger = LoggerFactory.getLogger(ExcelProcessor.class);
      
          public void parseExcelFile(File excelFile) throws Exception{
              final List<Employee> employeeList = new ArrayList<Employee>();
              InputStream xmlMapping = new BufferedInputStream(ExcelProcessor.class.getClassLoader().getResourceAsStream("proBroMapping.xml"));
              ReaderConfig.getInstance().setUseDefaultValuesForPrimitiveTypes(true);
              ReaderConfig.getInstance().setSkipErrors(true);
              InputStream inputXLS;
              try{
                  XLSReader mainReader = ReaderBuilder.buildFromXML(xmlMapping);
                  inputXLS = new BufferedInputStream(new FileInputStream(excelFile));
                  final Map<String, Object> beans = new HashMap<String, Object>();
                  beans.put("employeeList", employeeList);
                  mainReader.read(inputXLS, beans);
                  System.out.println("Employee data are extracted successfully from the Excel file, number of Employees is: "+employeeList.size());
              } catch(java.lang.OutOfMemoryError ex){
                  // Case of a very large file that exceed the capacity of the physical memory
                     ex.printStackTrace();
                  throw new Exception(ex.getMessage());
              } catch (IOException ex) {
                  logger.error(ex.getMessage());
                  throw new Exception(ex.getMessage());
              } catch (SAXException ex) {
                  logger.error(ex.getMessage());
                  throw new Exception(ex.getMessage());
              } catch (InvalidFormatException ex) {
                  logger.error(ex.getMessage());
                  throw new Exception(ex.getMessage());
              } finally {
                  IOUtils.closeQuietly(inputStream);
              }
      
          }
      
      }
      

      希望这对遇到此类问题的人有所帮助!

      【讨论】:

        【解决方案6】:

        你也可以考虑使用这个小库excelorm

        【讨论】:

          【解决方案7】:

          检查以下存储库。它是通过在头脑中保持“易用性”而开发的。 https://github.com/millij/poi-object-mapper

          初始版本已发布到Maven Central

          <dependency>
              <groupId>io.github.millij</groupId>
              <artifactId>poi-object-mapper</artifactId>
              <version>1.0.0</version>
          </dependency>
          

          与杰克逊类似。像下面这样注释你的 bean..

          @Sheet
          public class Employee {
              // Pick either field or its accessor methods to apply the Column mapping.
              ...
              @SheetColumn("Age")
              private Integer age;
              ...
              @SheetColumn("Name")
              public String getName() {
                  return name;
              }
              ...
          }
          

          然后阅读..

          ...
          final File xlsxFile = new File("<path_to_file>");
          final XlsReader reader = new XlsReader();
          List<Employee> employees = reader.read(Employee.class, xlsxFile);
          ...
          

          就目前而言,支持所有原始数据类型。仍在努力添加对DateFormula 等的支持。

          希望这会有所帮助。

          【讨论】:

            【解决方案8】:

            我想找到一种将 xls/xlsx 文件解析为 pojo 列表的简单方法。经过一番搜索,我没有发现任何方便的东西,而是希望快速开发它。现在我可以通过简单地调用来获得 pojos:

            InputStream is = this.getClass().getResourceAsStream("/ExcelUtilsTest.xlsx");
            List<Pojo> pojos = ExcelToPojoUtils.toPojo(Pojo.class, is);
            

            有兴趣的可以看看:

            https://github.com/ZPavel/excelToPojo

            【讨论】:

              【解决方案9】:

              查看使用 Apache POI 将 xlsx 表绑定到对象列表的 example

              这是一个非常简单的示例,展示了如何使用 Apache POI 将 Microsoft Excel (xlsx) 工作表转换为对象列表。

              这个想法只是在要将工作表列映射到的字段上定义注释@ExcelCellInfo。然后将根据注释属性使用反射绑定工作表单元格。

              使用示例:

              ExcelSheetDescriptor<RowClassSample> sheetDescriptor = new ExcelSheetDescriptor<>(RowClassSample.class).setHasHeader();
              List<RowClassSample> rows = ExcelUtils.readFirstSheet("pathToFile.xlsx", sheetDescriptor);
              

              以及要绑定的类:

              public class RowClassSample {
              
                  @ExcelCellInfo(index = 0)
                  private long serial;
              
                  @ExcelCellInfo(index = 1)
                  private String name;
              
                  @ExcelCellInfo(index = 2, cellParser = CellNumericAsStringParser.class)
                  private String registrationNumber;
              
                  @ExcelCellInfo(index = 3, cellParser = CellPercentageParser.class)
                  private Double percentage;
              
                  @ExcelCellInfo(index = 6)
                  private String reason;
              
                  @ExcelCellInfo(index = 4)
                  private String notes;
              
                  @ExcelCellInfo(index = 5, cellParser = CellBooleanYesNoArParser.class)
                  private boolean approval;
              
                  // getters & setters
              }
              

              【讨论】:

              猜你喜欢
              • 2013-01-10
              • 2014-10-23
              • 2013-12-01
              • 2018-01-13
              • 1970-01-01
              • 2020-01-21
              • 1970-01-01
              • 1970-01-01
              • 2011-09-06
              相关资源
              最近更新 更多