JAVA操作excel-POI及EasyExcel

POI及EasyExcel

POI官网

EasyExcel官网

EasyExcel使用说明

POI

操作excel的组件列表:

HSSF : 它被用来读取和写入MS-Excel文件的xls格式。—03版本excel

XSSF : 它是用于MS-Excel中xlsx文件格式。—07版本excel

1. 导入依赖

  • 03版本excel,.xls表格文件,最多支持65535行数据
<!--xls 03版本 -->
       <dependency>
           <groupId>org.apache.poi</groupId>
           <artifactId>poi</artifactId>
           <version>3.9</version>
       </dependency>
  • 07版本excel,.xlsx表格文件,不限行数
<!--xls 07版本 xlsx-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.9</version>
        </dependency>

2. 对象分析

​ 表格操作会涉及到4个对象:

​ 工作表:WorkBook

​ 工作簿:Sheet

​ 行:Row

​ 单元格(列):Cell

3. 代码操作-写

#### 3.1 写入03版本excel---HSSF
 @Test
    public void test03() throws IOException {
         String path = "V:\\study\\excel\\excel-poi";		//获取项目路径
        //创建03版本的xls表格
        Workbook workbook = new HSSFWorkbook(); 		//创建工作表
        Sheet sheet = workbook.createSheet("人员统计表");		//创建工作簿
        ---sheet
        Row row = sheet.createRow(0); 			//创建行,0代表第一行
        Cell cell1 = row.createCell(0);        //创建列,此处创建了坐标 1,1的单元格
        cell1.setCellValue("数量");			//设置单元格的值
        Cell cell2 = row.createCell(1);        //此处创建坐标1,2的单元格
        cell2.setCellValue(10);
        //03版本,文件名以xls结尾
        FileOutputStream outputStream = new FileOutputStream(path + "人员统计表.xls");  //创建文件输出流
        workbook.write(outputStream);
        outputStream.close();		//关闭流
        System.out.println("表格生成完成");
    }

03版本如果一次性写入数据超过65535,会报异常。

3.2 写入07版本excel—XSSF
  @Test
    public void test07() throws IOException {
        String path = "V:\\study\\excel\\excel-poi";		//获取项目路径
        //创建07版本的xls表格
        Workbook workbook = new XSSFWorkbook();
        //创建工作表---sheet
        Sheet sheet07 = workbook.createSheet("人员统计表");
        //创建行
        Row row = sheet07.createRow(0);//第一行
        //创建列,此处创建了坐标 1,1的单元格
        Cell cell1 = row.createCell(0);
        cell1.setCellValue("数量");
        //此处创建坐标1,2的单元格
        Cell cell2 = row.createCell(1);
        cell2.setCellValue(100);
        //07版本,文件名以xls结尾
        FileOutputStream outputStream = new FileOutputStream(path + "人员统计表.xlsx");
        workbook.write(outputStream);
        outputStream.close();
        System.out.println("表格生成完成");
    }
3.3 大数据写07版本—SXSSF
 @Test
    public void test07Bigdata() throws IOException {
          String path = "V:\\study\\excel\\excel-poi";		//获取项目路径
        long begin = System.currentTimeMillis();
        //创建07版本的xlsx表格,处理大数据
        Workbook workbook = new SXSSFWorkbook();
        //创建工作表---sheet
        Sheet sheet = workbook.createSheet("测试大数据S");
        for (int rowNo=0 ;rowNo<100000;rowNo++){
            Row row = sheet.createRow(rowNo);
            for (int cellNo = 0 ;cellNo<10;cellNo++){
                Cell cell = row.createCell(cellNo);
                cell.setCellValue(cellNo);
            }
        }
        //07版本,文件名以xlsx结尾
        FileOutputStream outputStream = new FileOutputStream(path + " 测试大数据S.xlsx");
        workbook.write(outputStream);
        outputStream.close();
        //使用SXSSF会产生临时文件,需要删除
        ((SXSSFWorkbook)workbook).dispose();
        long end = System.currentTimeMillis();
        System.out.println("over");
        System.out.println(end - begin);
    }
  • HSSF,一次性最多写入65535行数据;
  • XSSF,一次性可以写入大量数据,但是耗时长;
  • SXSSF,XSSF的加速版,大数据写入快(过程中会产生临时文件,需要删除)。

代码操作-读

@Test
    public void TestReadCellType() throws IOException {
          String path = "V:\\study\\excel\\excel-poi";		//获取项目路径
        FileInputStream fileInputStream = new FileInputStream(path+"\\人员信息表.xls");
        Workbook workbook = new HSSFWorkbook(fileInputStream);
        //获取工作簿
        Sheet sheet = workbook.getSheetAt(0);
        Row rowTitle = sheet.getRow(0);    		//	获取第一行,标题行
        if(rowTitle!=null){
            //获取列数
            int cells = rowTitle.getPhysicalNumberOfCells();
            for (int cellNo = 0; cellNo <cells ; cellNo++) {
                Cell cell = rowTitle.getCell(cellNo);
                if(cell!=null){
                    int cellType = cell.getCellType();
                    System.out.print("|");
                    System.out.print(cell.getStringCellValue());
                }
            }
        }
        System.out.println();
        //读取除标题行外的所有数据
        int rows = sheet.getPhysicalNumberOfRows();
        for (int rowNo = 1 ; rowNo <rows ; rowNo++) {
            Row row = sheet.getRow(rowNo);
            if(row!=null){
                //获取所有列
                int cells = row.getPhysicalNumberOfCells();
                for (int cellNo = 0; cellNo <cells; cellNo++) {
                    Cell cell = row.getCell(cellNo);
                    int cellType = cell.getCellType();
                    switch (cellType){
                        case HSSFCell.CELL_TYPE_STRING://字符串
                            String value = cell.getStringCellValue();
                            System.out.println("String:"+value);
                            break;
                        case HSSFCell.CELL_TYPE_BOOLEAN://boolean类型
                            System.out.println("Boolean:"+String.valueOf(cell.getBooleanCellValue()));
                            break;
                        case HSSFCell.CELL_TYPE_NUMERIC://数字类型
                            //数字类型要判断是日期还是数字
                            if(HSSFDateUtil.isCellDateFormatted(cell)){
                                System.out.print("日期:");
                                Date date = cell.getDateCellValue();
                                System.out.println(new DateTime(date).toString("yyyy-MM-dd HH:mm:ss"));
                            }else {
                                //如果是数字,为了防止数字类型过大,先转为字符类型,再获取
                                cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                                System.out.println("转为字符串输出"+cell.getStringCellValue());
                            }
                            break;
                        case HSSFCell.CELL_TYPE_ERROR:
                            System.out.println("数据类型错误");
                    }
                }
            }
        }
        fileInputStream.close();
    }

读取操作,需要针对不同的数据类型做判断,用不同的api获取值;

EasyExcel

导入依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.9</version>
        </dependency>

代码操作-写

  • 创建数据实体类
public class TestData {  //	这边全都是标题行
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("年龄")
    private Integer age;
    @ExcelProperty("生日")
    private Date birth;
    @ExcelIgnore
    private String ingore;
}
  • 初始化数据
  public static List<TestData> data(){
    List<TestData> list = new ArrayList<TestData>();
        for (int i = 0; i <5 ; i++) {
            TestData testData = new TestData();
            testData.setName("人员"+i);
            testData.setAge(i);
            testData.setBirth(new DateTime(new Date()).toDate());
            list.add(testData);
        }
        return list;
    }
  • 写入数据

       @Test
        public void simpleWrite() throws FileNotFoundException {
            String path = "V:\\study\\excel";
            String fileName = path+"\\easyExcelWrite.xlsx";
            //指定用哪个class去写
            //write(文件名,格式类)
            //sheet(工作簿名称)
            //doWrite(数据)
           EasyExcel.write(fileName,TestData.class).sheet("人员").doWrite(data());
        }
    
  • 执行结果
    在这里插入图片描述

代码操作-读

  1. 创建监听器,继承AnalysisEventListener类,重写方法,方法中写逻辑

    public class DataDemoListener extends AnalysisEventListener<TestData> {
            private static final Logger LOGGER = LoggerFactory.getLogger(DataDemoListener.class);
            /**
             * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
             */
            private static final int BATCH_COUNT = 5;
            List<TestData> list = new ArrayList<TestData>();
    		//解析每一条数据都会执行此方法
        public void invoke(TestData testData, AnalysisContext analysisContext) {
            LOGGER.info("解析到一条数据:{}", JSON.toJSONString(testData));
            System.out.println(testData);
        }
    		//所有数据解析完成了 都会来调用此方法
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("解析成功");
        }
    }
    
  2. 读取数据,将监听器作为参数传入

        @Test
        public void simpaleRead(){
            String path = "V:\\study\\excel";
            String fileName = path+"\\easyExcelWrite.xlsx";
            // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
            EasyExcel.read(fileName, TestData.class, new DataDemoListener()).sheet().doRead();
        }
    
  3. 执行结果
    在这里插入图片描述

参考狂神说java。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值