读取Excel文档的两种写法

时间:2021-08-07
本文章向大家介绍读取Excel文档的两种写法,主要包括读取Excel文档的两种写法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

需用读取Excel文档,所以了解了一下大概做法,并整理如下:
1.使用jxl,创建单元格对象,读取文档内容,优点是代码简单,按行读取,缺点是在智能处理03版本的EXCEL文件,如下 :
导入依赖:

1 <!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl -->
2         <dependency>
3             <groupId>net.sourceforge.jexcelapi</groupId>
4             <artifactId>jxl</artifactId>
5             <version>2.6.12</version>
6         </dependency>

接下来是代码实现,逻辑比较简单就不多说了

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
 
public class simple {
  public static void main(String[] args) {
    try {
      File file = new File("XXX.xls" +""); // 创建文件对象
      Workbook wb = Workbook.getWorkbook(file); // 从文件流中获取Excel工作区对象(WorkBook)
      Sheet sheet = wb.getSheet(0); // 从工作区中取得页(Sheet)
      for (int i = 0; i < sheet.getRows(); i++) { // 循环打印Excel表中的内容
        for (int j = 0; j < sheet.getColumns(); j++) {
          Cell cell = sheet.getCell(j, i);
          System.out.printf(cell.getContents()+" ");
        }
        System.out.println();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

2.使用阿里巴巴的fastExcel,代码稍微复杂一点,功能多,能处理03和07版本的
我的目录结构如下:

 导入依赖

 <!--EasyExcel-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.0-beta2</version>
        </dependency>
 
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.1</version>
        </dependency>
 
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
 
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
 
        <!--fastJson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.72</version>
        </dependency>
 
        <!--druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>

根据EXCEL文档表头信息编辑实体类,即pojo中的TableInfo

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
 
@Data
public class TableInfo {
 
  @ExcelIgnore
  @ExcelProperty("序号")
  private Integer num;
 
  //字段    数据类型    字段标题    字段说明    字段来源
  @ExcelProperty("字段")
  private String fieldName;
 
  @ExcelProperty("数据类型")
  private String dataType;
 
  @ExcelProperty("字段标题")
  private String comment1;
 
  @ExcelProperty("字段说明")
  private String comment2;
 
  @ExcelIgnore
  @ExcelProperty("字段来源")
  private String url;
}

dao层用于处理数据库,如果不需要存储到数据库可以不写具体实现:

1 import ExcelRead.pojo.TableInfo;
2 import java.util.List;
3  
4 public class TableDao {
5   public void save(List<TableInfo> list) {
6     // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
7   }
8 }

具体实现代码:

 1 import ExcelRead.dao.TableDao;
 2 import ExcelRead.pojo.TableInfo;
 3 import com.alibaba.excel.context.AnalysisContext;
 4 import com.alibaba.excel.event.AnalysisEventListener;
 5 import com.alibaba.fastjson.JSON;
 6 import org.slf4j.Logger;
 7 import org.slf4j.LoggerFactory;
 8 import java.util.ArrayList;
 9 import java.util.List;
10  
11 public class TableDataListener extends AnalysisEventListener<TableInfo> {
12   private static final Logger LOGGER = (Logger) LoggerFactory.getLogger(TableDataListener.class);
13   /**
14    * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
15    */
16   private static final int BATCH_COUNT = 200;
17   List<TableInfo> list = new ArrayList<TableInfo>();
18   /**
19    * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
20    */
21   private TableDao tableDao;
22   public TableDataListener() {
23     // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
24     tableDao = new TableDao();
25   }
26   /**
27    * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
28    *
29    * @param tableDao
30    */
31   public TableDataListener(TableDao tableDao) {
32     this.tableDao = tableDao;
33   }
34   /**
35    * 这个每一条数据解析都会来调用
36    *
37    * @param data
38    *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
39    * @param context
40    */
41   @Override
42   public void invoke(TableInfo data, AnalysisContext context) {
43     System.out.println(JSON.toJSONString(data));
44     list.add(data);
45     // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
46     if (list.size() >= BATCH_COUNT) {
47       saveData();
48       // 存储完成清理 list
49       list.clear();
50     }
51   }
52   /**
53    * 所有数据解析完成了 都会来调用
54    *
55    * @param context
56    */
57   @Override
58   public void doAfterAllAnalysed(AnalysisContext context) {
59     // 这里也要保存数据,确保最后遗留的数据也存储到数据库
60     saveData();
61     LOGGER.info("所有数据解析完成!");
62   }
63   /**
64    * 加上存储数据库
65    */
66   private void saveData() {
67    // System.out.println("{}条数据,开始存储数据库!"+ list.size());
68     tableDao.save(list);
69     LOGGER.info("存储数据库成功!");
70   }
71 }

到这里基本就结束了,最后来个测试文件

 1 import ExcelRead.listener.TableDataListener;
 2 import ExcelRead.pojo.TableInfo;
 3 import com.alibaba.excel.EasyExcel;
 4 import org.junit.Test;
 5  
 6 public class readTest {
 7   @Test
 8   public void simpleRead() {
 9     // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
10     String fileName ="XXX.xlsx";
11  
12     // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
13     EasyExcel.read(fileName, TableInfo.class, new TableDataListener()).sheet().doRead();
14   }
15 }

原文地址:https://www.cnblogs.com/sha-shar/p/15111812.html