[Software Tools] easyExcel Concise Guide

easyExcel Profile

Java field parsing, generating more famous Excel framework Apache poi, jxl and so on. But they are there is a very serious problem is the loss of memory. If your system concurrency is not possible, then okay, but once up will be complicated by OOM or JVM frequent full gc.

easyExcel Alibaba is a open source excel a processing framework, to use simple, save memory known .

75M (46W line 25) of Excel 64M memory read within 1 minute (of course, the rapid mode faster, but the memory footprint will be a little more in 100M)

The main reason easyExcel greatly reduced memory consumption is not at parse Excel file data loaded into memory all at once, but from reading the data rows on disk, one by one resolution.

FIG easyExcel and the POI is at analytical comparison Excel FIG.

easyExcel by using an analytical model line by line, and the analysis result of the notification processing line (AnalysisEventListener) in the observer model.

It outlined the features and principles easyExcel above, on other issues easyExcel can make reference to this article . Here's to introduce through code how to use easyExcel.

Quick Start Guide

Read Excel file uploads

Let's show how to use easyExcel under by a user to read information Liezi.

step1: Create a user class information

@Data
public class UserInfo extends BaseRowModel {

    @ExcelProperty(index = 0)
    private String name;

    @ExcelProperty(index = 1)
    private int age;

    @ExcelProperty(index = 2)
    private String address;

}

step2: Create a subclass AnalysisEventListener

/**
 * 每解析一行会回调invoke()方法。
 * 整个excel解析结束会执行doAfterAllAnalysed()方法
 */

//有个很重要的点   不能被spring管理,要每次读取excel都要new。
//这边就会有一个问题:如果UserInfoDataListener中需要用到Spring中的主键怎么办?
public class UserInfoDataListener extends AnalysisEventListener<UserInfo> {

    Logger logger = LoggerFactory.getLogger(UserInfoDataListener.class);

    //每次读取100条数据就进行保存操作
    private static final int BATCH_COUNT = 100;
    //由于每次读都是新new UserInfoDataListener的,所以这个list不会存在线程安全问题
    List<UserInfo> list = new ArrayList<>();

    //这个组件是Spring中的组件,这边推荐两种方法注入这个组件
    //第一种就是提供一个UserInfoDataListener的构造方法,这个方法提供一个参数是UserInfoDataListener类型
    //另外一种方法就是将 UserInfoDataListener 这个类定义成 UserService 实现类的内部类(推荐这种方式)
    //private UserService userService;

    @Override
    public void invoke(UserInfo data, AnalysisContext analysisContext) {
        logger.info("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        logger.info("所有数据解析完成!");
    }

    private void saveData() {
        logger.info("{}条数据,开始存储数据库!", list.size());
        //保存数据
        //userService.save(list);
        logger.info("存储数据库成功!");
    }

}

step3: Read excel


public class EasyExcelDemo {

    public static void main(String[] args) throws Exception {
        InputStream fis = new FileInputStream("D:\\UserInfo.xlsx");

        AnalysisEventListener listener = new UserInfoDataListener();

        ExcelReader excelReader = EasyExcel.read(fis, UserInfo.class, listener).build();
        ReadSheet readSheet = EasyExcel.readSheet(0).build();
        ReadSheet readSheet2 = EasyExcel.readSheet(1).build();
        excelReader.read(readSheet);
        // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
        excelReader.finish();
    }

}

Only 3 steps above can be read in the Excel.

Download Excel file


public class ExcelUtil {

    public static OutputStream getOutputStream(String fileName, HttpServletResponse response)
            throws Exception{
        try{
            fileName = URLEncoder.encode(fileName,"utf-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            //此处指定了文件类型为xls,如果是xlsx的,请自行替换修改
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xls");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Cache-Control", "max-age=0");
            return response.getOutputStream();
        } catch (IOException e){
            throw new Exception("导出文件失败!");
        }
    }

    public static void writeExcel(HttpServletResponse response, List<? extends BaseRowModel> list, String fileName,
                                  String sheetName, Class clazz) throws Exception {
        ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLS);
        Sheet sheet = new Sheet(1, 0, clazz);
        sheet.setSheetName(sheetName);
        writer.write(list, sheet);
        writer.finish();
    }

}

In the Controller this way as long as we like to call the following on the line.


    @RequestMapping(value = "/file/testExcelDownload")
    public void testExcelDownload(HttpServletRequest request,HttpServletResponse response){
        //以下信息从数据库中查出
        List<ExcelInfo> excelInfos = new ArrayList<>();
        ExcelInfo info1 = new ExcelInfo();
        ExcelInfo info2 = new ExcelInfo();
        excelInfos.add(info1);
        excelInfos.add(info2);
        info1.setIssuerName("name1");
        info1.setRiskLevel("level1");
        info2.setIssuerName("name1");
        info2.setRiskLevel("level1");
        try {
            String fileName = "excelInfo";
            String sheetName = "sheet1";
            ExcelUtil.writeExcel(response, excelInfos, fileName, sheetName, ExcelInfo.class);
        } catch(Exception e){
            log.error("模板下载失败",e);
        }

    }

In the part of the exported Excel, easyExcel also offers custom styles, insert tables, inserting pictures and other functions, there is a more interesting feature is the Excel template filling function. For more information refer to the function of official documents .

Guess you like

Origin www.cnblogs.com/54chensongxia/p/11990312.html