EasyExcle使用小结

导读:本篇文章讲解 EasyExcle使用小结,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

1、EasyExcle优点

EasyExcle是阿里巴巴开源的excle处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是再解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。使用观察者模式将读取的数据通过AnalysisEventListener进行处理。

        <!-- 使用easyexcle -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.6</version>
        </dependency>

2、EasyExcle使用

首次将测试文件展示一下:
sheet1
sheet2
测试的excle一共有两个sheet分别是“个人信息”“公司信息”

首先根据excle的内容定义实体:个人信息(UserData )、公司信息(CompanyData )。
UserData.java

public class UserData {

    @ExcelProperty(value = "姓名")
    private String name;

    @ExcelProperty(value = "性别")
    private String sex;

    @ExcelProperty(value = "年龄")
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "DataDemo{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

CompanyData.java

public class CompanyData {

    @ExcelProperty(value = "公司名称")
    private String compName;

    @ExcelProperty(value = "地址")
    private String address;

    @ExcelProperty(value = "类型")
    private String type;

    @ExcelProperty(value = "创办日期")
    private String createDate;

    public String getCompName() {
        return compName;
    }

    public void setCompName(String compName) {
        this.compName = compName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getCreateDate() {
        return createDate;
    }

    public void setCreateDate(String createDate) {
        this.createDate = createDate;
    }

    @Override
    public String toString() {
        return "CompanyData{" +
                "compName='" + compName + '\'' +
                ", address='" + address + '\'' +
                ", type='" + type + '\'' +
                ", createDate='" + createDate + '\'' +
                '}';
    }
}

2.1、读取excle文件(方式一)

直接读取方式

    /**
     * 通过doReadSync方法直接读取
     */
    public static void readSync() {
        long start = System.currentTimeMillis();
        String fileName = "test.xls";
        try (InputStream in = EasyExcelDemo.class.getClassLoader().getResourceAsStream(fileName)) {
            //1、可以通过sheetNo读取sheet页
            //List<DataDemo> list = EasyExcelFactory.read(in).autoCloseStream(Boolean.TRUE).sheet(0).doReadSync();
            //2、可以通过sheetName读取sheet页
            List<UserData> list = EasyExcelFactory.read(in)
                    .autoCloseStream(Boolean.TRUE)  //选择自动关闭流
                    .sheet("个人信息")
                    .doReadSync();
            System.out.println(list.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "ms");
    }

main方法测试结果:

[{0=张三, 1=, 2=18.0}, {0=李四, 1=, 2=19.0}, {0=李思思, 1=, 2=19.0}, {0=王玲玲, 1=, 2=18.0}, {0=郭德纲, 1=, 2=40.0}, {0=范冰冰, 1=, 2=35.0}, {0=李茂贞, 1=, 2=37.0}, {0=虞姬, 1=, 2=19.0}, {0=楚霸王, 1=, 2=33.0}]
耗时:228ms

2.2、读取excle文件(方式二)

首先需要定义一个自己Listener来继承AnalysisEventListener,并且实现里面的invokedoAfterAllAnalysed方法

public class UserDatalListener extends AnalysisEventListener<UserData> {
    //存放解析数据
    List<UserData> datas = new ArrayList<>();
    //这个是批量操作的临界值
    int count = 5;
    @Override
    public void invoke(UserData userData, AnalysisContext analysisContext) {
        System.out.println(userData.toString());
        datas.add(userData);
        if(datas.size() >= count){
            saveData(datas);
            datas.clear();
        }
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        System.out.println("解析完成了");
        saveData(datas);
    }
    /**
     * 保存数据到数据库
     * @param userData
     */
    public void saveData(List<UserData> userData){
        System.out.println("入库 " + userData.size() + " 条数据");
    }
}

读取excle的代码如下:

    /**
     * 使用继承AnalysisEventListener的Listen方式来读取excle
     */
    public static void readExcle() {
        long start = System.currentTimeMillis();
        String fileName = "test.xls";
        try (InputStream in = EasyExcelDemo.class.getClassLoader().getResourceAsStream(fileName);) {
            EasyExcelFactory.read(in, UserData.class, new UserDatalListener())
                    .autoCloseStream(Boolean.TRUE)  //选择自动关闭流
                    .sheet()
                    .doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "ms");
    }

main方法测试结果:

DataDemo{name='张三', sex='男', age='18.0'}
DataDemo{name='李四', sex='男', age='19.0'}
DataDemo{name='李思思', sex='女', age='19.0'}
DataDemo{name='王玲玲', sex='女', age='18.0'}
DataDemo{name='郭德纲', sex='男', age='40.0'}
入库 5 条数据
DataDemo{name='范冰冰', sex='女', age='35.0'}
DataDemo{name='李茂贞', sex='男', age='37.0'}
DataDemo{name='虞姬', sex='女', age='19.0'}
DataDemo{name='楚霸王', sex='男', age='33.0'}
解析完成了
入库 4 条数据
耗时:297ms

2.3、读取多个sheet的excle文件

读取两个sheet需要根据每一个sheet匹配不同的实体,当然也可以直接使用LinkedHashMap不定义实体取实现。

/**
 *  关于公司信息的解析
 */
public class CompanyDatalListener extends AnalysisEventListener<CompanyData> {
    //存放解析数据
    List<CompanyData> datas = new ArrayList<>();
    //这个是批量操作的临界值
    int count = 5;
    @Override
    public void invoke(CompanyData companyData, AnalysisContext analysisContext) {
        System.out.println(companyData.toString());
        datas.add(companyData);
        if (datas.size() >= count) {
            saveData(datas);
            datas.clear();
        }
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        System.out.println("解析完成了");
        saveData(datas);
    }
    /**
     * 保存数据到数据库
     *
     * @param userData
     */
    public void saveData(List<CompanyData> userData) {
        System.out.println("入库 " + userData.size() + " 条数据");
    }
}

读取两个sheet的代码实现如下

    /**
     * 读取多个Sheet页的Excle
     */
    public static void read2SheetsExcel() {
        String fileName = "test.xls";
        //开始读取excle
        try (InputStream in = EasyExcelDemo.class.getClassLoader().getResourceAsStream(fileName)) {
            ExcelReader excelReader = EasyExcelFactory.read(in).build();
            //读取Sheet0
            ReadSheet readSheet0 = EasyExcelFactory.readSheet("个人信息")
                    .head(UserData.class)
                    .registerReadListener(new UserDatalListener())
                    .build();
            //读取Sheet1
            ReadSheet readSheet1 = EasyExcelFactory.readSheet("公司信息").
                    head(CompanyData.class).
                    registerReadListener(new CompanyDatalListener())
                    .build();
            //读取两个Sheet
            excelReader.read(readSheet0, readSheet1);
            //读取完了记得关闭
            excelReader.finish();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

使用main方法测试结果:

DataDemo{name='张三', sex='男', age='18.0'}
DataDemo{name='李四', sex='男', age='19.0'}
DataDemo{name='李思思', sex='女', age='19.0'}
DataDemo{name='王玲玲', sex='女', age='18.0'}
DataDemo{name='郭德纲', sex='男', age='40.0'}
入库 5 条数据
DataDemo{name='范冰冰', sex='女', age='35.0'}
DataDemo{name='李茂贞', sex='男', age='37.0'}
DataDemo{name='虞姬', sex='女', age='19.0'}
DataDemo{name='楚霸王', sex='男', age='33.0'}
解析完成了
入库 4 条数据
CompanyData{compName='阿里巴巴', address='北京', type='电商', createDate='2000.0'}
CompanyData{compName='百度', address='北京', type='搜索', createDate='1999.0'}
CompanyData{compName='腾讯', address='深圳', type='聊天', createDate='2001.0'}
CompanyData{compName='中原银行', address='郑州', type='银行', createDate='2014.0'}
解析完成了
入库 4 条数据

2.4、写excle文件

通过输出流直接将excle内容输出

    /**
     * 将数据写入到指定文件
     *
     * @throws FileNotFoundException
     */
    public static void writeExcle() {
        UserData userData = new UserData();
        userData.setName("leo825");
        userData.setAge("25");
        userData.setSex("男");
        List<UserData> addList = new ArrayList<>();
        addList.add(userData);
        //定义一个输出流
        try(FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\WorkSpace\\IDEA_WorkSpace\\sortalgorithm-demos\\src\\main\\resources\\out.xls"));) {
            EasyExcelFactory.write(fileOutputStream, UserData.class)
                    .autoCloseStream(Boolean.TRUE) //选择自动关闭流
                    .sheet("个人信息")
                    .doWrite(addList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

如果是在web上下载的话可以使用如下代码:

	@RequestMapping("/download")
	public void download(HttpServletResponse response) throws Exception {
		//测试数据
	    UserData userData = new UserData();
        userData.setName("leo825");
        userData.setAge("25");
        userData.setSex("男");
        List<UserData> addList = new ArrayList<>();
        addList.add(userData);

		//输出流输出文件
		response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("测试", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
        EasyExcelFactory.write(response.getOutputStream(),UserData.class)
        				.autoCloseStream(Boolean.TRUE) //选择自动关闭流
        				.sheet("个人信息")
        				.doWrite(addList);
	}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72656.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!