第十三章——jXLS Reader

本文介绍了jXLS的jxls-reader模块,用于读取XLS文件并将Excel数据填充到Java Beans中。主要内容包括Maven依赖、XML配置文件的构建、通过sheet索引映射数据、错误处理机制以及转换机制。通过XML映射文件定义单元格到Java Bean属性的关系,实现Excel数据的高效读取。

jXLS提供jxls-reader模块,用于读取XLS文件并使用Excel数据填充Java Beans。XML配置文件用于表示如何解析Excel文件,如何填充数据。

1    Maven依赖

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

2    使用XML配置文件构建XLSReader

为了使用jXLS-Reader解析Excel文件,使用读取的数据填充Java数据,首先,你需要构建一个XLSReader对象。最简单的方式使用特定XML配置文件构建XLSReader对象。

让我们使用departmentdata.xls Excel文件和一些部门数据演示该方法。

单元格和Java对象之间的映射关系在XML配置文件中。让我们看看departmentdata.xls文件中的Sheet1的xml映射文件。

<?xml version="1.0" encoding="ISO-8859-1"?>
<workbook>
    <worksheet name="Sheet1">
        <section startRow="0" endRow="6">
            <mapping cell="B1">department.name</mapping>
            <mapping cell="A4">department.chief.name</mapping>
            <mapping cell="B4">department.chief.age</mapping>
            <mapping cell="D4">department.chief.payment</mapping>
            <mapping row="3" col="4">department.chief.bonus</mapping>
        </section>
        <loop startRow="7" endRow="7" items="department.staff" var="employee" varType="org.jxls.reader.sample.Employee">
            <section startRow="7" endRow="7">
                <mapping row="7" col="0">employee.name</mapping>
                <mapping row="7" col="1">employee.age</mapping>
                <mapping row="7" col="3">employee.payment</mapping>
                <mapping row="7" col="4">employee.bonus</mapping>
            </section>
            <loopbreakcondition>
                <rowcheck offset="0">
                    <cellcheck offset="0">Employee Payment Totals:</cellcheck>
                </rowcheck>
            </loopbreakcondition>
        </loop>
    </worksheet>
</workbook>

如上所示,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标签定义:

<mapping cell="B1">department.name</mapping>

你也可以使用cell属性指定映射的单元格,使用标签体作为完整属性名。所谓完整属性名,类似于department.name或department.chief.payment这种Java对象属性导航。其它单元格选项使用单元格行和列数(基于0)。

<mapping row="3" col="4">department.chief.bonus</mapping>

这是定义单元格E4与属性department.chief.bonus的映射。

loop元素定义Excel行循环块。该元素应该包含startRow和endRow属性指定循环块的开始和结束行。使用循环快数据填充context中的items属性名的集合。var属性指定在迭代内部section时如何引用该集合中的item。varTyp属性定义集合item的完整Java类名。

<loop startRow="7" endRow="7" items="department.staff" var="employee" varType="org.jxls.reader.sample.Employee">

loop元素可以包含任意数量的内部section和loop元素,并且必须包含loopbreakcondition定义。该标签标示中断循环的条件。在我们的例子中,该值为“Employee Payment Totals:”。

<loopbreakcondition>
    <rowcheck offset="0">
        <cellcheck offset="0">Employee Payment Totals:</cellcheck>
    </rowcheck>
</loopbreakcondition>

这是所有你需要知道的创建XML映射配置文件的内容。下面是使用ReaderBuilder类使用XML映射文件和departmentdata.xls构建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索引映射。

<?xml version="1.0" encoding="ISO-8859-1"?>
<workbook>
    <worksheet idx="0">
        <section startRow="0" endRow="6">
            <mapping cell="B1">department.name</mapping>
            <mapping cell="A4">department.chief.name</mapping>
            <mapping cell="B4">department.chief.age</mapping>
            <mapping cell="D4">department.chief.payment</mapping>
            <mapping row="3" col="4">department.chief.bonus</mapping>
        </section>
        <loop startRow="7" endRow="7" items="department.staff" var="employee" varType="org.jxls.reader.sample.Employee">
            <section startRow="7" endRow="7">
                <mapping row="7" col="0">employee.name</mapping>
                <mapping row="7" col="1">employee.age</mapping>
                <mapping row="7" col="3">employee.payment</mapping>
                <mapping row="7" col="4">employee.bonus</mapping>
            </section>
            <loopbreakcondition>
                <rowcheck offset="0">
                    <cellcheck offset="0">Employee Payment Totals:</cellcheck>
                </rowcheck>
            </loopbreakcondition>
        </loop>
    </worksheet>
</workbook>

因此,使用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类注册。

转载于:https://my.oschina.net/leeck/blog/1842772

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值