Java 操作 Excel 竟如此简单

用户头像
生命在于折腾
关注
发布于: 2020 年 06 月 20 日
Java操作Excel竟如此简单

使用阿里开源项目easyexcel覆盖多场景操作Excel



sorry,最近备战618更新有些慢了,但是咱们的工作只会迟到不会缺席呀哈哈~



前言



在工作中,使用excel表格处理数据是很常见的操作,本文就来讲解下如何使用开源轮子实现下载、导入、导出的功能。



在之前,很多Java程序员都喜欢使用POI的类库来操作excel,但是非常的不方便,不仅代码写的很臃肿,还要处理各种office版本兼容问题,最怕的就是使用不当很容易造成内存溢出,因此今天给大家推荐阿里的一款开源项目 easyexcel



项目介绍



easyexcel是一款快速、简单避免OOM的java处理Excel工具



github地址:https://github.com/alibaba/easyexcel



Start:15.2k



看了下,两天前项目团队还有在完善代码,可见项目还是挺活跃的





项目集成



使用idea开发工具简单创建了一个easyexcel-demo项目,加入了web模块以及easyexcel maven依赖,依赖如下:



<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --><dependency>   <groupId>com.alibaba</groupId>   <artifactId>easyexcel</artifactId>   <version>2.2.4</version></dependency>​版本的话我们使用2.2.4,2020年6月份上传的,算是最新的版本了。





好了,我们就开始写功能了。1、实现已有Excel模板下载很多系统有数据批量导入的场景,因为在页面上批量加数据时间成本太大了,但是一般导入的时候得按照一定的格式改,所以一般好的产品会先让用户下载一个带有格式的文档,然后按照格式写好以后上传导入,我们来实现这个功能吧!创建模板文件首先我们创建一个模板文件,内容如图





将模板文件放置再项目里然后我们把它放在项目的配置文件下,如图





然后下载代码也很简单,主要分为加载资源->读取资源->写入响应流@RestController@RequestMapping("/user")public class UserController {    /**     * 下载模板     */    @GetMapping("/downloadTemplate")    public void downloadTemplate(HttpServletResponse response) throws Exception {        ClassPathResource classPathResource = new ClassPathResource("excelTemplate/easyexcel.xlsx");        InputStream inputStream = classPathResource.getInputStream();        Workbook workbook = new HSSFWorkbook(inputStream);        response.setContentType("application/vnd.ms-excel");        response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode("easyexcel.xlsx", "utf-8"));        response.setHeader("Access-Control-Expose-Headers", "content-Disposition");        OutputStream outputStream = response.getOutputStream();        workbook.write(outputStream);        outputStream.flush();        outputStream.close();   }}​测试启动项目,访问,如图所示,可以下载。





2.写入数据并生成文件将数据导出到文档这种场景可以说是最常见的了,那么怎么使用easyExcel快速实现呢,我们同样还是以上面的模板为例定义模型映射对象 UserExcelModel@Datapublic class UserExcelModel  extends BaseRowModel implements Serializable {​    @ExcelProperty(value = "用户名", index = 0)    private String name;​    @ExcelProperty(value = "年龄", index = 1)    private Integer age;​    @ExcelProperty(value = "手机号", index = 2)    private String mobile;​    @ExcelProperty(value = "性别", index = 3)    private String sex;}​定义这个对象的目的有两个:当前场景下写入文件作为model对象构造数据以及下个要讲的数据读取了。简要代码流程如下:定义列标题->创建sheet->自定义字体和风格->构造数据->写入数据->写入到浏览器响应流 /**     * 导出数据     */    @GetMapping("/exportData")    public void exportData(HttpServletResponse response) throws Exception {        XSSFWorkbook workbook = new XSSFWorkbook();​        String []columnNames = {"用户名","年龄","手机号","性别"};​        Sheet sheet = workbook.createSheet();        Font titleFont = workbook.createFont();        titleFont.setFontName("simsun");        titleFont.setBold(true);        titleFont.setColor(IndexedColors.BLACK.index);​        XSSFCellStyle titleStyle = workbook.createCellStyle();        titleStyle.setAlignment(HorizontalAlignment.CENTER);        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);        titleStyle.setFillForegroundColor(IndexedColors.YELLOW.index);        titleStyle.setFont(titleFont);​        Row titleRow = sheet.createRow(0);​        for (int i = 0; i < columnNames.length; i++) {            Cell cell = titleRow.createCell(i);            cell.setCellValue(columnNames[i]);            cell.setCellStyle(titleStyle);       }        //模拟构造数据        List<UserExcelModel> dataList = new ArrayList<>();        dataList.add(new UserExcelModel("张三",12,"13867098765","男"));        dataList.add(new UserExcelModel("张三1",12,"13867098765","男"));        dataList.add(new UserExcelModel("张三2",12,"13867098765","男"));        dataList.add(new UserExcelModel("张三3",12,"13867098765","男"));​        //创建数据行并写入值        for (int j = 0; j < dataList.size(); j++) {            UserExcelModel userExcelModel = dataList.get(j);            int lastRowNum = sheet.getLastRowNum();            Row dataRow = sheet.createRow(lastRowNum + 1);            dataRow.createCell(0).setCellValue(userExcelModel.getName());            dataRow.createCell(1).setCellValue(userExcelModel.getAge());            dataRow.createCell(2).setCellValue(userExcelModel.getMobile());            dataRow.createCell(3).setCellValue(userExcelModel.getSex());       }        response.setContentType("application/vnd.ms-excel");        response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode("easyexcel.xls", "utf-8"));        response.setHeader("Access-Control-Expose-Headers", "content-Disposition");        OutputStream outputStream = response.getOutputStream();        workbook.write(outputStream);        outputStream.flush();        outputStream.close();   }​





3.读取数据





我们再回过头来看我们定义的这个Model对象,通过指定index可以对应读取的excel里面的列,然后定义的数据类型就对应到excel里面具体的值,来看看如何实现:    @PostMapping("/readExcel")    public List<UserExcelModel> readExcel(@RequestParam("file") MultipartFile file){        List<UserExcelModel> list = new ArrayList<>();        try {            list = EasyExcel.read(file.getInputStream(),UserExcelModel.class,new ModelExcelListener()).sheet().doReadSync();       } catch (IOException e) {            e.printStackTrace();       }        return list;   }看完代码是不是心里一万头草拟吗飞过~ 看完这个代码再看用poi工具处理的,是不是相当简洁了。对于代码中的ModelExcelListener,其实是我们自定义的一个读取监听类,贴贴代码:public static class ModelExcelListener extends AnalysisEventListener {        private List<Object> datas = new ArrayList<>();        /**         * 通过 AnalysisContext 对象还可以获取当前 sheet,当前行等数据         */        @Override        public void invoke(Object data, AnalysisContext context) {            //数据存储到list,供批量处理,或后续自己业务逻辑处理。            log.info("读取到数据{}",data);            datas.add(data);            //根据业务自行处理,可以写入数据库等等       }​        //所以的数据解析完了调用        @Override        public void doAfterAllAnalysed(AnalysisContext context) {            log.info("所有数据解析完成");       }   }这是一个读取数据监听类,有特殊业务需求的都可以在这个类里面自定义实现,比如边读边写库啊,数据过滤和处理等等,用的好了绝对是一把利剑。PostMan模拟调用





控制台输出





总结通过本篇文章,我们演示了如何使用easyexcel进行一些excel的操作,在实际的项目应用中,可以对以上示例代码进行进一步的封装,使其不管是读取、导出等操作都能几行代码搞定,这个就得根据情况大家自由发挥了。项目代码获取1.地址:https://github.com/pengziliu/GitHub-code-practice/2.点击底部阅读原文| 模块 | 所属开源项目 | 项目介绍 | | --- | --- | --- | --- || springboot_api_encryption | rsa-encrypt-body-spring-boot | Spring Boot接口加密,可以对返回值、参数值通过注解的方式自动加解密 。 | simpleimage-demo | simpleimage | 图片处理工具类,具有加水印、压缩、裁切等功能 | xxl-job-demo | xxl-job | 分布式定时任务使用场景 | xxl-sso-demo | xxl-sso | 单点登录功能 | vuepress-demo |vuepress |建立自己的知识档案库| xxl-conf-demo |xxl-conf |分布式配置中心| Shardingsphere-demo |Shardingsphere |分库分表| easyexcel-demo |easyexcel |excel操作工具类



发布于: 2020 年 06 月 20 日 阅读数: 61
用户头像

生命在于折腾

关注

还未添加个人签名 2018.04.25 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
感谢分享,期待更多好内容。
2020 年 06 月 20 日 16:53
回复
没有更多了
Java操作Excel竟如此简单