基于自定义的Excel解析框架的使用范例

来源:互联网 发布:在淘宝买ipad可靠吗 编辑:程序博客网 时间:2024/06/05 15:05

首先可能会有一个Model,与数据库的一张表对应:

package com.bob.config.mvc.model;import java.io.Serializable;/** * Excel映射的Model * * @author dell-7359 * @create 2017-10-19 19:46 */public class ExcelModel implements Serializable {    private static final long serialVersionUID = -422292418932719315L;    private Integer id;    private String userName;    private String password;    private Integer age;    private String telephone;    private String adress;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public Integer getAge() {        return age;    }    public void setAge(Integer age) {        this.age = age;    }    public String getTelephone() {        return telephone;    }    public void setTelephone(String telephone) {        this.telephone = telephone;    }    public String getAdress() {        return adress;    }    public void setAdress(String adress) {        this.adress = adress;    }}

但是我们的映射Model可能不是表对应的model,可能是属性字段不足,也不应该在表对应的model上修改东西,所以我们自定义了一个扩展类,继承自ExcelModel,有一些额外的属性:

package com.bob.config.mvc.model;import java.util.Date;import com.bob.config.mvc.excelmapping.ExcelColumn;import com.bob.config.mvc.excelmapping.ExcelColumn.Column;import com.bob.config.mvc.excelmapping.ExcelMapping;import com.bob.config.mvc.excelmapping.PropertyInitializer;/** * Excel映射的Model扩展类 * * @author dell-7359 * @create 2017-10-19 19:55 */@ExcelMapping(titleRow = 2, dataRow = 3, sheetAt = 0)public class ExcelModelExtends extends ExcelModel implements PropertyInitializer<ExcelModelExtends> {    private static final long serialVersionUID = 445175433808433505L;    @ExcelColumn(value = Column.G,last = true)    private String description;    private Date parseTime;    @ExcelColumn(value = Column.A,key = true)    public Integer getId() {        return super.getId();    }    @ExcelColumn(value = Column.B)    public String getUserName() {        return super.getUserName();    }    @ExcelColumn(value = Column.C)    public String getPassword() {        return super.getPassword();    }    @ExcelColumn(value = Column.D)    public Integer getAge() {        return super.getAge();    }    @ExcelColumn(value = Column.E)    public String getTelephone() {        return super.getTelephone();    }    @ExcelColumn(value = Column.F)    public String getAdress() {        return super.getAdress();    }    public String getDescription() {        return description;    }    public void setDescription(String description) {        this.description = description;    }    public Date getParseTime() {        return parseTime;    }    public void setParseTime(Date parseTime) {        this.parseTime = parseTime;    }    /**初始化Model对象     * @return     */    @Override    public ExcelModelExtends initProperties() {        ExcelModelExtends modelExtends = new ExcelModelExtends();        modelExtends.setParseTime(new Date());        return modelExtends;    }}

我们在ExcelModelExtends 类上添加了一个注解ExcelMapping,指明Excel内标题行,数据起始行,以及数据页码。ExcelModelExtends 实现了一个属性初始化接口,每解析一行数据时通过此接口方法得到ExcelModelExtends 实例,同时做一些初始化工作。我们再ExcelModelExtends 重写自ExcelModel的getter方法上添加了ExcelColumn注解,表名这个字段对应Excel第几列,同时是否是数据行与行之间唯一性的标识,可以有多个key字段,当每个key字段均相等时行数据重复,重复校验失败。

假设Excel数据如下:
这里写图片描述

解析测试代码如下:

package com.bob.test.concrete.excelmapping;import java.io.File;import java.io.IOException;import java.util.Collection;import com.bob.config.mvc.excelmapping.Excel;import com.bob.config.mvc.excelmapping.ExcelInstance;import com.bob.config.mvc.excelmapping.ExcelMappingProcessor;import com.bob.config.mvc.model.ExcelModelExtends;import org.junit.Test;/** * Excel解析工具类测试 * * @author  * @create 2017-09-26 16:56 */public class ExcelMappingTest {    private ExcelMappingProcessor<ExcelModelExtends> processor;    @Test    public void testParsing() throws Exception {        Excel excel = new Excel("C:\\Users\\dell-7359\\Desktop\\Excel原始数据.xlsx");        processor = new ExcelMappingProcessor<ExcelModelExtends>(excel,ExcelModelExtends.class);        boolean success = processor.process();        Collection<ExcelInstance<ExcelModelExtends>> results = processor.getCorrectResult();        System.out.println(results.size());        if(!success){            File errorFile = new File("C:\\Users\\dell-7359\\Desktop\\Excel原始数据_错误回写.xlsx");            excel.write(errorFile);        }    }}

运行测试用例,数据正常时能得到解析成功的对象集合。

当单元格数据类型与字段类型不匹配时:

这里写图片描述

运行单元测试,重新打开上传的Excel文件:
这里写图片描述

解析框架会一次性解析完所有的Excel行,同时将所有的类型不匹配单元格上添加批注,批注上指明错误信息,同时对key=true的字段对应的单元格的标题行(显示第3行,序号为2)上插入批注。

这里写图片描述

当修改了单元格数据时,不需要删除批注新,可以直接上传,解析框架在解析之间会抹去错误批注,不会影响错误标识的第二次添加。

当两行的数据的key=true字段值均相应相等时:

这里写图片描述

运行解析测试代码:

这里写图片描述

默认第一行数据时正确行,key值相等第二行为重复行,在重复行的最后一个单元格之后添加错误信息,标识醒目背景色,修改完错误单元格时删除错误信息列。重新上传。

解析框架还支持对表单校验的结果BindingResul,将其错误新写入对应的单元格中。

正常流程是用户上传了Excel之后,解析,如果有错误信息。将错误信息写入Excel的二进制流中,同时将二进制数据缓存起来,当用户看到解析异常时,下载标识了错误信息的excel,将缓存的二进制信息重新生成一个Excel供用户下载,此Excel中已经包含了相应的错误信息。

原创粉丝点击