java解析導入excel表格轉為實體類javabean,根據實體類中的中文名稱


最近公司需求解析excel,一開始使用poi做的挺好的,后來直接上了幾十萬條數據的excel文件,內存直接溢出了,網上查到apache poi還提供了專門處理海量數據的方法,使用sax解析,果然用了內存使用率下降,但是不能解析xls文件,只能解析xlsx文件,所以把工具簡單封裝了一下,如果是xls的用傳統方式解析,如果是xlsx的大文件,用sax,這樣靈活一定,詳見md文件

(建議前往github查看最新內容)

https://github.com/hellojamie/ebatis  下載項目源碼

https://gitee.com/hellojamie/ebatis

 

Ebatis

用於解析excel表格內容到 java bean 目前支持xls、xlsx格式文件 對於大數據量文件自動使用sax方式解析,防止內存溢出

目錄(記得看注意):

  1. 開始
  2. 擴展功能
  3. 注意

開始

因為經常有改動,需要手動打包發布

// Maven導入第三方poi依賴,或者直接把master pull下來發布到本地
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>
<dependency> 
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>
<dependency>
	<groupId>xerces</groupId>
	<artifactId>xercesImpl</artifactId>
	<version>2.9.1</version>
</dependency>

  

首先你需要創建好你的實體類,假設現在有這樣一個excel表格需要解析

姓名 手機號 生日
王文娟 18888888888 1996-01-01
大美麗 16666666666 1996-01-01

首先你需要一個實體類 有幾點要求,必須正確封裝,包含get\set方法 屬性上包含必要的Mapping注解,key屬性填入與表格對應的名稱,屬性類型根據需要自己定義

package cc.ebatis.controller;

import java.io.File;

import cc.ebatis.bean.People;
import cc.ebatis.impl.Init;
import cc.ebatis.pojo.ActionContext;

public class Test {
	public static void main(String[] args) {
		File file = new File("c://Users//Pei//Desktop//pei.xlsx");
		Init<People> init = new Init<People>(file, People.class, false);
		System.out.println("init===="+init);
		ActionContext<People> act = init.start();
		System.out.println("act===="+act);
	}

}

  

package cc.ebatis.bean;

import java.util.Date;

import cc.ebatis.annotation.Mapping;

public class People {
	@Mapping(key = "姓名")
	private String name;
	
	@Mapping(key = "手機號")
	private String phone;
	
	@Mapping(key = "生日")
	private Date birth;
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public String getPhone() {
		return phone;
	}
 
	public void setPhone(String phone) {
		this.phone = phone;
	}
 
	public Date getBirth() {
		return birth;
	}
 
	public void setBirth(Date birth) {
		this.birth = birth;
	}

	@Override
	public String toString() {
		return "People [name=" + name + ", phone=" + phone + ", birth=" + birth + "]";
	}
	
	
}

  

  然后將你的文檔以流的方式加載進來,通過以下代碼開始解析

// Init接受一個InputStream對象,以及一個實體對象
// 調用start開始
// 通過ActionContext獲取需要的信息
// 參數依次為-文件-實體class-是否去重
File file = new File("excel.xlsx");	
Init<ExcelPojo> init = new Init<ExcelPojo>(file, ExcelPojo.class, false);
ActionContext<ExcelPojo> act = init.start();

  (注意:如果要去重的話請重寫實體中的hashCode和equals方法,內部使用set來去重,false表示不去重) ActionContext中包含了所需要的所有信息,信息格式如下,這里以json的形式展示

{
  "sheets":[
    {
      "line":5,
         "sheetName":"Sheet1",
         "column":6,
         "correctLine":5,
         "blankLineSize":0,
         "errorLineSize":0,
         "repeatLineSize":0,
      "info":[
        {
          "date":1331481600000,
          "name":"王文娟",
          "phone":"15035214458"
        },
        {
          "date":1331481600000,
          "name":"大美麗",
          "phone":"14555874458"
        }
      ],
      "blankLine":[],
         "errorLine":[],
         "repeatLine":[]
    }
  ],
  "fileType":"XLSX",
   "SheetSize":1,
   "fileSizeByte":9138,
   "useSax":true,
   "distinct":false,
   "result":true
}

  

屬性名 含義
sheets sheet數組
line 解析當前sheet一共多少行數據,不算表頭
sheetName sheet的名稱
column 列數
info 實體對象數組,包含實體的列表,也就是行數據
correctLine 實際正確解析出的數量(行數)
blankLineSize 空行的數量
errorLineSize 錯誤行的數量,包括正則不通過被刪除的
repeatLineSize 重復行的數量
fileType 文件類型
blankLine 空白行的行號-數組
errorLine 錯誤行的行號-數組
repeatLine 重復行的行號-數組
fileSizeByte 文件大小(字節)
useSax 是否使用了sax方式
distinct 是否去重
result 最后是否解析成功,如果中間出錯則是false
sheetSize 文件中有幾個sheet
useSax 是否使用sax解析,即是否解析的是xlsx文件
distinct 是否去重

使用ActionContext的getXXX方法獲取上面的內容

擴展功能

@Mapping注解有三個非必選屬性

  1.  
    @Mapping(key = "手機號", rex = "^[0-9]{11}$", delNull = true, length = 11)
  2.  
    private String phone;
屬性名 含義 是否必填
key 填寫與excel文件頭的映射名稱 必填
rex 填寫解析內容時使用的正則表達式,如果不符合正則則不賦值 非必填
delNull 如果該屬性為null的話,是否刪除整條信息,默認false不刪除 非必填
length 填寫提取內容的最大長度,默認不限制 非必填

@LineNumber注解,獲取當前記錄是第幾行,不算表頭那行

  1.  
    @LineNumber
  2.  
    private Integer line;

@MappingSheetName注解,將sheet名稱作為屬性值添加

  1.  
    @MappingSheetName
  2.  
    private String type;

注意

  • 解析xlsx大文件的時候,POI本身會占據較大內存,例如100W行15列,POI自身將消耗400M+的內存,加上解析出來的內容會大於這個值,以100W為例大概需要700M+內存
  • 實體中請使用包裝類,不支持int等類型,請使用Integer
  • 列與列之間不能包含表頭為空的列,即不能有空列將信息隔開,如果有,以空列前一列為末尾解析
  • excel文件請使用第一行表頭,其余行信息的標准格式,如果有合並單元格情況,可能會解析失敗(可以包含空行和空單元格,會自動過濾,但必須有表頭)
  • 實體類的屬性不嚴格要求與列的數量一致,根據需要添加映射注解即可
  • 實體類 的屬性和表頭的順序沒有嚴格要求,只要key匹配即可
  • 如果需要去重,請重寫實體的hashCode和equals方法,內部使用HashSet方式去重,重寫時請注意
  • 最后是否解析成功請以result屬性為准


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM