jXLS提供jxls-reader模块,用于读取XLS文件并使用Excel数据填充Java Beans。XML配置文件用于表示如何解析Excel文件,如何填充数据。
1 Maven依赖
org.jxls jxls-reader 2.0.3
2 使用XML配置文件构建XLSReader
为了使用jXLS-Reader解析Excel文件,使用读取的数据填充Java数据,首先,你需要构建一个XLSReader对象。最简单的方式使用特定XML配置文件构建XLSReader对象。
让我们使用 Excel文件和一些部门数据演示该方法。
单元格和Java对象之间的映射关系在XML配置文件中。让我们看看文件中的Sheet1的xml映射文件。
department.name department.chief.name department.chief.age department.chief.payment department.chief.bonus employee.name employee.age employee.payment employee.bonus Employee Payment Totals:
如上所示,xml文件的根元素为workbook,可以包含任意数量的子worksheet元素,worksheet标签应该包含name属性表示Excel Sheet的名称(我们的例子中为Sheet1)。
worksheet元素可以包含任意数量的section和loop子元素。
section元素表示一个简单的单元格块。块的第一和最后一行使用startRow和endRow属性指定。
在当前版本中,你必须为整个Excel Sheet指定section,因此,它完全被分割成多个section。这意味着,即使你不打算读取,例如第一行,也需要创建一个空section(section没有mapping,但指定startRow/endRow属性),以至于这些行在XML文件中体现。不需要的行将直接跳过,所有其他部分将按要求阅读。XML单元格到Java Bean属性的映射使用mapping标签定义:
department.name
你也可以使用cell属性指定映射的单元格,使用标签体作为完整属性名。所谓完整属性名,类似于department.name或department.chief.payment这种Java对象属性导航。其它单元格选项使用单元格行和列数(基于0)。
department.chief.bonus
这是定义单元格E4与属性department.chief.bonus的映射。
loop元素定义Excel行循环块。该元素应该包含startRow和endRow属性指定循环块的开始和结束行。使用循环快数据填充context中的items属性名的集合。var属性指定在迭代内部section时如何引用该集合中的item。varTyp属性定义集合item的完整Java类名。
loop元素可以包含任意数量的内部section和loop元素,并且必须包含loopbreakcondition定义。该标签标示中断循环的条件。在我们的例子中,该值为“Employee Payment Totals:”。
Employee Payment Totals:
这是所有你需要知道的创建XML映射配置文件的内容。下面是使用ReaderBuilder类使用XML映射文件和构建XLSReader类读取XLS数据填充相应Java Bean的代码:
InputStream inputXML = new BufferedInputStream(getClass().getResourceAsStream(xmlConfig));XLSReader mainReader = ReaderBuilder.buildFromXML( inputXML );InputStream inputXLS = new BufferedInputStream(getClass().getResourceAsStream(dataXLS));Department department = new Department();Department hrDepartment = new Department();List departments = new ArrayList();Map beans = new HashMap();beans.put("department", department);beans.put("hrDepartment", hrDepartment);beans.put("departments", departments);XLSReadStatus readStatus = mainReader.read( inputXLS, beans);
3 通过sheet索引映射
Jxls Reader支持通过sheet索引映射。
department.name department.chief.name department.chief.age department.chief.payment department.chief.bonus employee.name employee.age employee.payment employee.bonus Employee Payment Totals:
因此,使用worksheet标签的idx属性替代name属性指定sheet索引。sheet索引从0开始。
4 错误处理
默认,如果jXLS读取某些单元格值失败将会停止进一步处理抛出XLSDataReadException。
你可以使用ReaderConfig类的setSkipErrors(true)方法覆盖该行为,允许跳过错误并继续处理。使用ReaderConfig.getInstance()方法获取ReaderConfig类的实例。
ReaderConfig.getInstance().setSkipErrors( true );
所有的错误消息存储在XLSReadStatus对象由read方法返回。XLSDataReadException可以包含该对象引用。我们可以使用getReadMessages()方法从XLSReadStatus分析XLSReadMessage对象。
5 转换机制
Jxls Reader继承Apache Commons Beanutils转换工具类执行Excel单元格值到Bean属性的实际转换。更多细节见ConvertUtil类。Jxls Reader使用org.apache.commons.beanutils.converters包为原始类型标准转换器。Jxls Reader为java.util.Date类型提供自定义DataConverter,使用Apache POI工具方法从Excel数据表现形式转换为Date类。
BeanUtils转换器转换错误时为原始类型返回一个默认值。在ReaderConfig类中注册这些类抛出一个ConversionException,覆盖这些行为。如果喜欢使用默认值,我们可以使用ReaderConfig类的setUseDefaultValuesForPrimitiveTypes(true)方法。例如:
ReaderConfig.getInstance().setUseDefaultValuesForPrimitiveTypes( true );
为了自定义转换器从Excel单元格到自定义属性类型,我们应该事先Converter接口,使用ConvertUtils类注册。