导入导出记录

1、.xls和.xlsx的区别

(1)文件格式不同。xls 是一个特有的二进制格式,其核心结构是复合文档类型的结构,而 xlsx 的核心结构是 XML 类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小。xlsx 中最后一个 x 的意义就在于此。

(2)版本不同。xls是excel2003及以前版本生成的文件格式,而xlsx是excel2007及以后版本生成的文件格式。

(3)兼容性不同。xlsx格式是向下兼容的,可兼容xls格式。

(4)读取方式有两种:使用导入jxl包的方式或者使用java中的poi(两种方式区别:导入jxl包的形式,只能处理xls格式;使用java中的poi的话,可以使用poi中的HSSFWorkBook来处理xls文件,使用XSSFWrokBook或者SXSSFWorkBook来处理xlsx格式的文件)

2、记录一下HSSFWorkBook,XSSFWrokBook和SXSSFWorkBook的区别

  用Java中的poi导出Excel时,我们需要考虑到Excel版本及数据量的问题。针对不同的Excel版本,要采用不同的工具类,如果使用错了,会出现错误信息。JavaPOI导出Excel有三种形式,分别是HSSFWorkbook、XSSFWorkbook和SXSSFWorkbook。

  HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls。是poi导出excel最常用的方式;但是此种方式的局限就是导出的行数至多为65535行,超出65536条后系统就会报错。此方式因为行数不足七万行所以一般不会发生内存不足的情况(OOM)

  XSSFWorkbook:是操作Excel2007后的版本,扩展名是.xlsx。这种形式的出现是为了突破HSSFWorkbook的65535行局限。其对应的是excel2007(1048576行,16384列)扩展名为“.xlsx”,最多可以导出104万行,不过这样就伴随着一个问题---OOM内存溢出,原因是你所创建的book、sheet、row和cell等此时是存在内存的并没有持久化。

  SXSSFWorkbook:是操作Excel2007后的版本,扩展名是.xlsx。从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的SXSSF方式。对于大型excel文件的创建,一个关键问题就是,要确保不会内存溢出。其实,就算生成很小的excel(比如几Mb),它用掉的内存是远大于excel文件实际的size的。如果单元格还有各种格式(比如,加粗,背景标红之类的),那它占用的内存就更多了。对于大型excel的创建且不会内存溢出的,就只有SXSSFWorkbook了。它的原理很简单,用硬盘空间换内存(就像hash map用空间换时间一样)。SXSSFWorkbook是streaming版本的XSSFWorkbook,它只会保存最新的excel rows在内存里供查看,在此之前的excel rows都会被写入到硬盘里(Windows电脑的话,是写入到C盘根目录下的temp文件夹)。被写入到硬盘里的rows是不可见的/不可访问的。只有还保存在内存里的才可以被访问到。

3、具体代码实现

(1)使用HSSFWorkBook来读取excel文件(.xls格式)

几点注意:

a、使用HSSFWorkBook不可读取xlsx格式,否则报错如下:

org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)

b、getFirstRowNum获取第一行的行号,getLastRowNum获取最后一行的行号;

  Row row = sheet.getRow(i)获取第i行

  row.getFirstCellNum()获取row行的第一列列号, row.getLastCellNum()获取row行的最后一列的列号

  row.getCell(j).getNumericCellValue()读取数值类型的值, row.getCell(j).getStringCellValue()读取字符串类型值

c、在遍历行或者列的时候,注意最后一行或者一列是读取不到的,不要用等于号,否则空指针异常。i < sheet.getLastRowNum()而不是i < =sheet.getLastRowNum()。

package com.netease.work.video_download.excel;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import java.io.File;
import java.io.FileInputStream;

/**

  • @author wangql

  • @date 2020/6/13 7:47

  • @描述
    */
    public class HSSFWorkBookTest {
    public static void main(String[] args) {
    File file = new File(“B:\seckill\test.xls”);
    try {
    FileInputStream fis = new FileInputStream(file.getAbsolutePath());
    HSSFWorkbook hwb = new HSSFWorkbook(fis);
    // int rows = hwb.getNumberOfSheets();
    Sheet sheet = hwb.getSheetAt(0);
    // 循环遍历每一行
    for(int i = sheet.getFirstRowNum(); i < sheet.getLastRowNum(); i++){
    // 循环遍历每一列
    Row row = sheet.getRow(i);
    for(int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++){
    if(row.getCell(j).getCellType() == CellType.NUMERIC){
    System.out.print((int)row.getCell(j).getNumericCellValue()+" “);
    }else if(row.getCell(j).getCellType() == CellType.STRING){
    System.out.print(row.getCell(j).getStringCellValue()+” ");
    }

             }
             System.out.println();
         }
    
     } catch (Exception e) {
         e.printStackTrace();
     }
    

    }
    }

(2)使用XSSFWorkBook来读取excel文件(.xlsx格式)

几点注意:

a、使用XSSFWorkBook不可读取xls格式,否则报错如下:

org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException: The supplied data appears to be in the OLE2 Format. You are calling the part of POI that deals with OOXML (Office Open XML) Documents. You need to call a different part of POI to process this data (eg HSSF instead of XSSF)

b、getFirstRowNum获取第一行的行号,getLastRowNum获取最后一行的行号;

  Row row = sheet.getRow(i)获取第i行

  row.getFirstCellNum()获取row行的第一列列号, row.getLastCellNum()获取row行的最后一列的列号

  row.getCell(j).getNumericCellValue()读取数值类型的值, row.getCell(j).getStringCellValue()读取字符串类型值

c、在遍历行或者列的时候,注意最后一行或者一列是读取不到的,不要用等于号,否则空指针异常。i < sheet.getLastRowNum()而不是i < =sheet.getLastRowNum()。

package com.netease.work.video_download.excel;

import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;

/**

  • @author wangql

  • @date 2020/6/13 7:48

  • @描述
    */
    public class XSSFWorkBookTest {
    public static void main(String[] args) {
    File file = new File(“B:\seckill\test.xlsx”);
    try {
    FileInputStream fis = new FileInputStream(file.getAbsolutePath());
    XSSFWorkbook swb = new XSSFWorkbook(fis);
    Sheet sheet = swb.getSheetAt(0);
    for(int i = sheet.getFirstRowNum(); i < sheet.getLastRowNum(); i++){
    Row row = sheet.getRow(i);
    for(int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++){
    if(row.getCell(j).getCellType() == CellType.NUMERIC){
    System.out.print((int)row.getCell(j).getNumericCellValue()+" “);
    }else if(row.getCell(j).getCellType() == CellType.STRING){
    System.out.print(row.getCell(j).getStringCellValue()+” ");
    }

             }
             System.out.println();
         }
    
     } catch (Exception e) {
         e.printStackTrace();
     }
    

    }
    }

(3)使用SXSSFWorkBook来读取excel文件(.xlsx格式)

几点注意:

a、使用SXSSFWorkBook不可读取xls格式,否则报错如下:

org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException: The supplied data appears to be in the OLE2 Format. You are calling the part of POI that deals with OOXML (Office Open XML) Documents. You need to call a different part of POI to process this data (eg HSSF instead of XSSF)

b、getFirstRowNum获取第一行的行号,getLastRowNum获取最后一行的行号;

  Row row = sheet.getRow(i)获取第i行

  row.getFirstCellNum()获取row行的第一列列号, row.getLastCellNum()获取row行的最后一列的列号

  row.getCell(j).getNumericCellValue()读取数值类型的值, row.getCell(j).getStringCellValue()读取字符串类型值

c、在遍历行或者列的时候,注意最后一行或者一列是读取不到的,不要用等于号,否则空指针异常。i < sheet.getLastRowNum()而不是i < =sheet.getLastRowNum()。

package com.netease.work.video_download.excel;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;

/**

  • @author wangql

  • @date 2020/6/13 7:48

  • @描述
    */
    public class SXSSFWorkBookTest {
    public static void main(String[] args) {
    File file = new File(“B:\seckill\test.xlsx”);
    try {
    FileInputStream fis = new FileInputStream(file.getAbsolutePath());
    XSSFWorkbook swb = new XSSFWorkbook(fis);
    Sheet sheet = swb.getSheetAt(0);
    for(int i = sheet.getFirstRowNum(); i < sheet.getLastRowNum(); i++){
    Row row = sheet.getRow(i);
    for(int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++){
    if(row.getCell(j).getCellType() == CellType.NUMERIC){
    System.out.print((int)row.getCell(j).getNumericCellValue()+" “);
    }else if(row.getCell(j).getCellType() == CellType.STRING){
    System.out.print(row.getCell(j).getStringCellValue()+” ");
    }

             }
             System.out.println();
         }
    
     } catch (Exception e) {
         e.printStackTrace();
     }
    

    }
    }

4、总结

(1)HSSFWorkBook,只能读取xls格式文件;XSSFWorkBook和SXSSFWorkBook只能读取xlsx格式的文件,根据自己的 文件格式选择使用不同的类型

(2)HSSFWorkBook处理excel格式的文件行数最大65535行,XSSFWorkBook能够处理最大1048576行,16384列的文件

(3)方法总结:

     a、一个excel文件中可以有多个sheet,获取所有sheet的过程,先使用getNumberOfSheets()获取所有sheet的数量,然后使用getSheetAt(index)的形式,类似于数组获取值的方式来获取每个sheet

     b、getFirstRowNum、getLastRowNum、getRow(i)、row.getFirstCellNum()、row.getLastCellNum()、getCellType()、getNumericCellValue、getStringCellValue等,见上述代码。注意获取单元格数据时候最好进行格式判断,根据不同的格式,选择使用不同的获取数据的格式,如果是CellType.NUMERIC类型,则使用getNumericCellValue获取数据;如果是CellType.STRING类型,则使用getStringCellValue读取数据。CellType.NUMERIC和CellType.STRING是poi依赖包中自定义的枚举类,可以自己查看。判断过程如下:

if(row.getCell(j).getCellType() == CellType.NUMERIC){
System.out.print((int)row.getCell(j).getNumericCellValue()+" “);
}else if(row.getCell(j).getCellType() == CellType.STRING){
System.out.print(row.getCell(j).getStringCellValue()+” ");
}

5、上述代码写在一个maven项目总,pom文件如下,几个核心依赖红色标出。

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

org.springframework.boot
spring-boot-starter-parent
2.3.0.RELEASE


com.netease.work
video_download
0.0.1-SNAPSHOT
video_download
Demo project for Spring Boot

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>4.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.1.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>4.1.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans -->
    <dependency>
        <groupId>org.apache.xmlbeans</groupId>
        <artifactId>xmlbeans</artifactId>
        <version>3.1.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>4.1.2</version>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>29.0-jre</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

6、除了使用poi中的HSSFWorkBook来读取xls格式的文件外,还可以通过jxl包来实现对xls文件的读取。可以通过手动下载jxlbao或者引入依赖的方式。直接贴代码。

package com.netease.work.video_download.excel;

import jxl.Sheet;
import jxl.Workbook;
import java.io.File;
import java.io.FileInputStream;

/**

  • @author wangql

  • @date 2020/6/13 7:47

  • @描述
    */
    public class WorkBookTest {
    public static void main(String[] args) {
    File file = new File(“B:\seckill\test.xlsx”);
    try {
    FileInputStream fis = new FileInputStream(file.getAbsolutePath());
    Workbook workBook = Workbook.getWorkbook(fis);
    // getNumberOfSheets是获取一个excel文件中的sheet数量,有多个sheet时可以通过循环遍历读取
    // int sheetNums = workBook.getNumberOfSheets();
    // getSheet通过下标读取指定的sheet,如果只有一个,则直接getSheet(0)获取此sheet
    Sheet sheet = workBook.getSheet(0);
    // 循环遍历读取此sheet下的各行数据
    for(int i = 0; i < sheet.getRows(); i++){
    // 循环读取一行数据中的各列数据
    for(int j = 0; j < sheet.getColumns(); j++){
    // 读取单元格i行j列的数据,注意getCell参数中,第一个是列,第二个是行
    System.out.print(sheet.getCell(j,i).getContents()+" ");
    }
    System.out.println();
    }
    } catch (Exception e) {
    e.printStackTrace();
    }

    }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者



你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值