栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Excel】Java 操作 Excel 的两种方式:POI、EasyExcel

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Excel】Java 操作 Excel 的两种方式:POI、EasyExcel

1. 了解 POI 和 EasyExcel

Java 中,常见的用来操作 Excel 的方式有 2 种:POI、EasyExcel。主要用于:对 Excel 进行导入、导出。

  • POI:Apache。一种原生操作 Excel(复杂)
    • HSSF : 读写 Microsoft Excel XLS 格式文档
    • XSSF : 读写 Microsoft Excel OOXML XLSX 格式文档
    • SXSSF : 读写 Microsoft Excel OOXML XLSX 格式文档(优化)
  • EasyExcel:更像是一种框架操作 Excel(简单)

它们的区别:

  • POI:把要写入的数据全加载到内存中,然后一次性地写数据。容易 OOM
  • EasyExcel:一行一行地写
2. POI

使用 POI 操作 Excel 时,API 中有三个不同的对象:HSSF 、XSSF、SXSSF。将它们进行比较:

  • HSSF:文档后缀 .xls(03版本的 excel)
    • 缺点:只能操作小于或等于 65536 行,否则,会抛出异常
    • 优点:过程中写入缓存,不操作磁盘,最后,一次性写入磁盘,速度快
  • XSSF:文档后缀 .xlsx(07版本的 excel)
    • 缺点:写数据时非常慢(边读边写),非常耗内存,也会发生内存溢出。如:100万条
    • 优点:可以写较大的数据量。如:20万条
  • SXSSF:文档后缀 .xlsx(07版本的 excel)
    • 缺点:需要清除临时文件(((SXSSFWorkbook) workBook).dispose())
    • 优点:可以写入更大的数据量。如:100万条。写数据速度快,占用更少的内存
2.1 写操作

创建一个 Maven 项目,引入依赖:


  org.apache.poi
  poi
  3.9



  org.apache.poi
  poi-ooxml
  3.9



  joda-time
  joda-time
  2.10.1

代码:

public class ExcelWriteTest {

    private String path = System.getProperty("user.dir");
	
	// 生成 03 版本的 excel
    public void testWrite03() throws Exception{
        // 1.创建一个工作簿
        Workbook workbook = new HSSFWorkbook();
        // 2.创建一个工作表
        Sheet sheet = workbook.createSheet("测试操作Excel03");
        // 3.创建一个行
        Row row1 = sheet.createRow(0);
        // 4.创建一个列
        Cell cell11 = row1.createCell(0);
        cell11.setCellValue("姓名");
        Cell cell12 = row1.createCell(1);
        cell12.setCellValue("zzc");

        Row row2 = sheet.createRow(1);
        Cell cell21 = row2.createCell(0);
        cell21.setCellValue("统计时间");
        Cell cell22 = row2.createCell(1);
        String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);

        // 生成表
        FileOutputStream out = new FileOutputStream(path + "测试操作Excel03.xls");
        workbook.write(out);
        out.close();
        System.out.println("测试操作Excel03.xls文件生成完毕!!");
    }

	// // 生成 07 版本的 excel
    public void testWrite07() throws Exception{
        // 1.创建一个工作簿
        Workbook workbook = new XSSFWorkbook();
        // 2.创建一个工作表
        Sheet sheet = workbook.createSheet("测试操作Excel07");
        // 3.创建一个行
        Row row1 = sheet.createRow(0);
        // 4.创建一个列
        Cell cell11 = row1.createCell(0);
        cell11.setCellValue("姓名");
        Cell cell12 = row1.createCell(1);
        cell12.setCellValue("zzc");

        Row row2 = sheet.createRow(1);
        Cell cell21 = row2.createCell(0);
        cell21.setCellValue("统计时间");
        Cell cell22 = row2.createCell(1);
        String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);

        // 生成表
        FileOutputStream out = new FileOutputStream(path + "测试操作Excel07.xlsx");
        workbook.write(out);
        out.close();
        System.out.println("测试操作Excel07.xlsx文件生成完毕!!");
    }

    public static void main(String[] args) throws Exception{
        ExcelWriteTest excelWriteTest = new ExcelWriteTest();
        excelWriteTest.testWrite03();
        excelWriteTest.testWrite07();
    }
}

生成后的 Excel 文件:

2.2 写操作之优化版本

如果在写入 07 版本的时候,有大量的数据写入,就会有可能出现内存溢出异常,且写入的时间会变得很慢,所以引入了该优化类。

public void testDemo3() throws Exception{
    long begin = System.currentTimeMillis();
    Workbook w = new SXSSFWorkbook();
    Sheet sheet = w.createSheet("Excel统计表");
    for (int rowNum = 0; rowNum < 100000; rowNum++) {
        Row row = sheet.createRow(rowNum);
        for (int cellNum = 0; cellNum < 10; cellNum++) {
            Cell cell = row.createCell(cellNum);
            cell.setCellValue(cellNum);
        }
    }
    long end = System.currentTimeMillis();
    System.out.println("消耗的时间为:"+ (end-begin));
    FileOutputStream fo = new FileOutputStream(path + "测试表07s.xlsx");
    w.write(fo);
    fo.close();
}
2.3 读操作
public class ExcelReadTest {

    private String path = System.getProperty("user.dir");

    public void testRead03() throws Exception{
        FileInputStream in = new FileInputStream(path + "测试操作Excel03.xls");
        Workbook workbook = new HSSFWorkbook(in);
        Sheet sheet = workbook.getSheetAt(0);
        Row row = sheet.getRow(0);
        Cell cell11 = row.getCell(0);
        Cell cell12 = row.getCell(1);
        System.out.println(cell11.getStringCellValue());
        System.out.println(cell12.getStringCellValue());
        in.close();
    }

    public void testRead07() throws Exception{
        FileInputStream in = new FileInputStream(path + "测试操作Excel07.xlsx");
        Workbook workbook = new XSSFWorkbook(in);
        Sheet sheet = workbook.getSheetAt(0);
        Row row = sheet.getRow(0);
        Cell cell11 = row.getCell(0);
        Cell cell12 = row.getCell(1);
        System.out.println(cell11.getStringCellValue());
        System.out.println(cell12.getStringCellValue());
        in.close();
    }

    public static void main(String[] args) throws Exception {
        ExcelReadTest excelReadTest = new ExcelReadTest();
        excelReadTest.testRead03();
        excelReadTest.testRead07();
    }
}
2.4 读取不同类型数据的 Excel


Excel 中要读取的数据类型:String、日期、布尔值等

public class ExcelReadTest {

    private String path = System.getProperty("user.dir");

    public void testCellType() throws Exception{
        FileInputStream in = new FileInputStream(path + "test.xls");
        Workbook workbook = new HSSFWorkbook(in);
        Sheet sheet = workbook.getSheetAt(0);
        // 获取标题
        Row rowTitle = sheet.getRow(0);
        if (null != rowTitle) {
            int cellCount = rowTitle.getPhysicalNumberOfCells();
            for (int cellNum = 0; cellNum < cellCount; cellNum++) {
                Cell cell = rowTitle.getCell(cellNum);
                if (null != cell) {
                    int cellType = cell.getCellType();
                    String cellValue = cell.getStringCellValue();
                    System.out.print(cellValue + "|");
                }
            }
        }
        System.out.println();

        // 获取表格的内容
        int rowCount = sheet.getPhysicalNumberOfRows();
        for (int rowNum = 1; rowNum < rowCount; rowNum++) {
            Row rowData = sheet.getRow(rowNum);
            if (null != rowData) {
                int cellCount = rowTitle.getPhysicalNumberOfCells();
                for (int cellNum = 0; cellNum < cellCount; cellNum++) {
                    Cell cell = rowData.getCell(cellNum);
                    if (null != cell) {
                        int cellType = cell.getCellType();
                        String cellValue = "";

                        switch (cellType) {
                            case Cell.CELL_TYPE_STRING:   // 字符串
                                System.out.println("【String】");
                                cellValue = cell.getStringCellValue();
                                break;
                            case Cell.CELL_TYPE_BOOLEAN:  // 布尔值
                                System.out.println("【Boolean】");
                                cellValue = String.valueOf(cell.getBooleanCellValue());
                                break;
                            case Cell.CELL_TYPE_BLANK:  // 空值
                                System.out.println("【BLANK】");
                                break;
                            case Cell.CELL_TYPE_NUMERIC:  // 数字、日期
                                if (HSSFDateUtil.isCellDateFormatted(cell)) {  // 日期
                                    System.out.println("【日期】");
                                    Date dateCellValue = cell.getDateCellValue();
                                    cellValue = new DateTime(dateCellValue).toString("yyyy-MM-dd");
                                } else {
                                    System.out.println("【数字】");
                                    // 防止数字过长
                                    cell.setCellType(Cell.CELL_TYPE_STRING);
                                    cellValue = cell.toString();
                                }
                                break;
                            case Cell.CELL_TYPE_ERROR:
                                System.out.println("【数据类型错误】");
                                break;
                        }
                        System.out.println(cellValue);
                    }
                }
            }
        }
        in.close();
    }

    public static void main(String[] args) throws Exception {
        ExcelReadTest excelReadTest = new ExcelReadTest();
        excelReadTest.testCellType();
    }
}
3. EasyExcel 3.1 写操作

添加依赖:


  com.alibaba
  easyexcel
  2.0.0-beta2

【注意】:一定要去掉 poi 的依赖,否则,会报错!!

public class DemoData {
    @ExcelProperty("字符串标题")
    private String string;
    @ExcelProperty("日期标题")
    private Date date;
    @ExcelProperty("数字标题")
    private Double doubleData;
    
    @ExcelIgnore
    private String ignore;
    //getter/setter
}
public class EasyExcelTest {

    private String path = System.getProperty("user.dir");

    private List data() {
        List list = new ArrayList();
        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;
    }

    public void easyExcelWrite() {
        // 写法1
        String fileName = path + "EasyExcelTest.xlsx";
        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
    }

    public static void main(String[] args) {
        EasyExcelTest easyExcelTest = new EasyExcelTest();
        easyExcelTest.easyExcelWrite();
    }
}

详细操作,请查看文档:EasyExcel

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/298724.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号