快速搞定---POI 和 EasyExcel

组件库学习—POI 和 EasyExcel

目前流行的操作 Excel 的第三方组件

easyExcel:阿里巴巴 java解析Excel工具,优化 POI, 不会出现内存溢出情况

常用场景

1、将数据导出为 Excel 表格,即导出数据

2、将 Excel 数据录入到数据库,即导入数据

Excel基本操作

导入 POI 组件依赖

   <!-- xls(03) -->
   <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.2</version>
    </dependency>
     <!-- xlsx(07) -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.2</version>
    </dependency>
String PATH = "C:\\Users\\86159\\OneDrive\\文档\\Finance Support System\\需求理解\\订单\\";
/**
 * Excel 07版本
 * @throws Exception
 */
@Test
public void testWrite07() throws Exception {
    // 1、创建一个工作簿
    Workbook workbook = new XSSFWorkbook();
    // 2、创建一个工作表
    Sheet sheet = workbook.createSheet("徐志摩散文诗集统计表");
    // 3、创建一个行(1, 1)
    Row row1 = sheet.createRow(0);
    // 4、创建一个单元格
    Cell cell11 = row1.createCell(0);
    cell11.setCellValue("陌上花开");
    Cell cell12 = row1.createCell(1);
    cell12.setCellValue("落叶");
    //第二行(2, 1)
    Row row2 = sheet.createRow(1);
    Cell cell21 = row2.createCell(0);
    cell21.setCellValue("最美的遇见");
    // 生成一张表 (IO 流) 07版本 文件后缀 xlsx
    FileOutputStream fileOutputStream = new FileOutputStream(PATH + "徐志摩散文诗集统计表07.xlsx");
    workbook.write(fileOutputStream);
    //关闭流
    fileOutputStream.close();
    System.out.println("徐志摩散文诗集统计表07 文件生成完毕");
}

注意:Excel 03版和07版对象的一个区别:文件后缀!

大数据量的写入

/**
 * Excel 07版本  大数据量写入
 * @throws Exception
 */
@Test
public void testWrite07BigData() throws Exception {
    // 1、创建一个工作簿
    Workbook workbook = new XSSFWorkbook();
    // 2、创建一个工作表
    Sheet sheet = workbook.createSheet("志摩诗集07版");
    // 3、创建行
    for (int rowNum = 0; rowNum < 20; rowNum++ ) {
        Row row = sheet.createRow(rowNum);
        // 4、创建单元格
        for (int cellNum = 0; cellNum < 10; cellNum++) {
            Cell cell = row.createCell(cellNum);
            cell.setCellValue(cellNum);
        }
    }
    System.out.println("=======over======");
    // 生成一张表 (IO 流) 07版本 文件后缀 xlsx
    FileOutputStream fileOutputStream = new FileOutputStream(PATH + "志摩诗集07版.xls");
    workbook.write(fileOutputStream);
    //关闭流
    fileOutputStream.close();
}

注意:数据批量导入!

大文件写HSSF:

​ 缺点:做多只能处理65536行,否则会抛出异常

​ 优点:过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快

大文件写XSSF:

​ 缺点:写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条

​ 优点:可以写较大的数据量,如20万条

大文件写SXSSF:

​ 优点:可以写非常大的数据量,如100万条甚至更多条,占用更少的内存

​ 缺点:过程中会产生临时文件,需要清理临时文件

@Test
public void testSxssfBigData() throws Exception {
    // 1、创建一个工作簿
    Workbook workbook = new SXSSFWorkbook();
    // 2、创建一个工作表
    Sheet sheet = workbook.createSheet();
    // 3、创建一行
    for (int rowNum = 0; rowNum < 655367; rowNum++) {
        Row row = sheet.createRow(rowNum);
        // 4、创建单元格
        for (int cellNum = 0; cellNum < 10; cellNum++) {
            Cell cell = row.createCell(cellNum);
            cell.setCellValue(cellNum);
        }
    }
    // 生成一张表 07 文件后缀 xlsx
    FileOutputStream fileOutputStream = new FileOutputStream(PATH + "testSXSSF07.xlsx");
    workbook.write(fileOutputStream);
    // 新版的不需要代码调用清除临时文件了
    // 关闭流
    fileOutputStream.close();
}

Excel 基本操作

@Test
public void testRead03() throws Exception{
    // 获取文件流
    FileInputStream inputStream = new FileInputStream( PATH + "志摩诗集03版.xls");
    // 1、创建一个工作簿,
    Workbook workbook = new HSSFWorkbook(inputStream);
    // 2、得到表
    Sheet sheet = workbook.getSheetAt(0);
    // 3、得到行
    Row row = sheet.getRow(0);
    // 4、得到列
    Cell cell = row.getCell(0);
    //读取值的时候一定要注意类型  这里(0,0)是string类型,所以可以这样写
    System.out.println(cell.getStringCellValue());
	// 关闭流
    inputStream.close();
}

难点—读取不同类型的数据

 	@Test
    public void testRead07() throws Exception{
        // 获取文件流
        FileInputStream inputStream = new FileInputStream( PATH + "副本RD 21M12 PO项目.xlsx");
        // 1、创建一个工作簿,
        Workbook workbook = new XSSFWorkbook(inputStream);
        // 2、得到表
        Sheet sheet = workbook.getSheetAt(1);
        // 3、获取标题内容
        Row rowTitle = sheet.getRow(0);
        // 4、得到列
        if(rowTitle != null){
            // 计数
            int cellCount = rowTitle.getPhysicalNumberOfCells();
            for (int cellNum = 0; cellNum < cellCount; cellNum++) {
                Cell cell = rowTitle.getCell(cellNum);
                if(cell != null){
                    CellType cellType = cell.getCellType();
                    String cellValue = cell.getStringCellValue();
                    System.out.print(cellValue + " | ");
                }
            }
        }
        System.out.println();
        //读取值的时候一定要注意类型
        //获取表中的内容
        DataFormatter dataFormatter = new DataFormatter();
        int rowCount = sheet.getPhysicalNumberOfRows();
        for (int rowNum = 1; rowNum < rowCount; rowNum++) {
            Row rowData = sheet.getRow(rowNum);
            if(rowData != null){
                // 读取列
                int cellCount = rowTitle.getPhysicalNumberOfCells();
                for (int cellNum = 0; cellNum < cellCount; cellNum++) {
                    System.out.print("[" + (rowNum+1) + "-" + (cellNum+1) + "]");
                    Cell cell = rowData.getCell(cellNum);
                    //匹配列的数据类型
                    if(cell!=null){
                        //获取单元格值 方法一 将数据类型都转换为string类型:
//                        CellType cellType = cell.getCellType();
//                        cell.setCellType(CellType.STRING);
                        //获取单元格值 方法二:
//                        dataFormatter.formatCellValue(cell);
                        System.out.println( dataFormatter.formatCellValue(cell));
                    }
                }
            }
        }

        inputStream.close();
    }

了解—计算公式

@Test
public void testFormula() throws Exception {
    FileInputStream fileInputStream = new FileInputStream(PATH + "test07.xlsx");
    Workbook workbook = new XSSFWorkbook(fileInputStream);
    Sheet sheet = workbook.getSheetAt(0);
    //(0,4)单元格有求和公式
    Row row = sheet.getRow(0);
    Cell cell = row.getCell(4);
    //拿到计算公式
    FormulaEvaluator formulaEvaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
    //输出单元格内容
    String formula = cell.getCellFormula();
    System.out.println(formula);
    //计算
    CellValue evaluate = formulaEvaluator.evaluate(cell);
    String cellValue = evaluate.formatAsString();
    System.out.println(cellValue);
}

EasyExcel 的使用

导入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.1</version>  <!--目前底层使用的是4.1版本的POI-->
</dependency>

写入测试

//最简单的写的对象
@Data
public class DemoData {
    @ExcelProperty("字符串标题")
    private String string;
    @ExcelProperty("日期标题")
    private Date date;
    @ExcelProperty("数字标题")
    private Double doubleData;
    /**
     * 忽略这个字段
     */
    @ExcelIgnore
    private String ignore;
}
// 通过数据生成,后面不需要重复写
private List<DemoData> data() {
    List<DemoData> list = ListUtils.newArrayList();
    for (int i = 0; i < 10; i++) {
        DemoData data = new DemoData();
        data.setString("字符串" + i);
        data.setDate(new Date());
        data.setDoubleData(0.56);
        list.add(data);
    }
    return list;
}
//最简单的写入操作
@Test
public void indexWrite() {
    String fileName = PATH + "EasyTest.xlsx";
    // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
    EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
}

小结

发现组件库学习还挺有趣的,有不足的地方希望大家多多批评指正呀,嘻嘻嘻

你可能感兴趣的:(SpringBoot系列,java,apache,spring,boot)