1. 程式人生 > >史上最全的excel讀寫技術分享

史上最全的excel讀寫技術分享

目錄

  • 簡介
  • 匯出excel常用的幾種方法
    • POI
    • CSV
    • jxl
    • jxls
    • easyexcel
  • 快速入門
    • 程式碼解讀
    • 總結
  • 常用API
    • 單元格樣式
    • 合併單元格
    • 資料樣式
    • 多sheet設定
    • 單元格新增超連結
      • 依賴
      • 使用版本
      • 中流砥柱
  • notes
    • 系統時間
    • 讀寫資料格式內建轉換器
    • ModelBuildEventListener
    • write
  • 讀寫流程分析
    • read
    • write
  • # 加入戰隊
    • 微信公眾號

此文章以獨家授權一下公眾號 :
【新華前後端開發】
【指令碼之家】

快速、簡單避免OOM的java處理Excel工具】 github上關於專案的介紹

簡介

poi使用userModel模式,這個模式的特點就是上手很容易。程式碼寫起來很複雜。而且公用的地方很少。導致每次讀寫excel都需要重新編寫。

EasyExcel使用SAX模式使得easyexcel可以節省記憶體。而且easyexcel解決了記憶體洩漏問題。如果想了解SAX模式開發那成本需要3~5天學習。

匯出excel常用的幾種方法

通過Java讀寫excel大概有以下幾種:
poi、csv、jxl、jxls 、easyPoi 、easyExcel
根據效能他們的排序:
jxl 、 easyexcel 、 csv 、  poi 、  easypoi 、  jxls

POI

  • POI是apache的一個開源專案。他是基於微軟提供對Java程式的一個API。通過它我們能控制excel的單元格的內容及樣式的讀取寫入。
  • 但是正是因為他的細節之處導致我們開發起來程式碼很多。而且無法抽離。

CSV

  • csv實際上就是一個文字,只不過通過office能夠開啟的一中文字。真正的excel物件如果通過普通的文字工具開啟你會發現實際是一個二進位制檔案。因為csv是一個文字,所以在讀寫他的時候實際就是文字的讀取。沒有POI的workbook、sheet、row 、cell 之說。所以讀寫的效率還是很快的。
  • 但是因為是文字所以我們無法控制單元格的樣式。比如樣式、加下拉框、合併單元格之類的。

jxl

  • jxl實際和POI差不多。兩者的理念一樣,都是通過表格物件--》單元頁--》行--》列--》單元格的邏輯去操作讀寫的。基本上常用的功能都是提供方法的。不同的是方法的傳參順序的不同。兩者在效能上的比較jxl效能更佳。
  • 因為POI的風靡。jxl並不是很熟知。筆者也是整理的時候發現jxl。暫時不知道jxl的缺點。非要指出缺點那麼就是他和poi的邏輯不一樣。編寫起來有點彆扭。

jxls

  • 這裡需要值得注意的是jxls和jxl一點關係都沒有。兩者的使用方法的邏輯也是天差萬別的。jxls更佳側重的是excel本身的模板的編寫。jxls是通過模板在注入資料進行渲染的一個框架。他的最大的有點就是程式碼量很少。基本上我們只需要準備好資料就可以進行匯出了。
  • 因為是基於模板的。所以jxls實現匯出的很簡單。但是實現讀取資料這裡就很不好辦了。這裡筆者暫時不知道如何實現。 這個問題就留給聰明的讀者吧!!!

    easypoi

  • easypoi和easyexcel很相似。兩者都是通過註解的方式實現excel表頭與實體物件的一種對映。一個@Excel 另一個是@ExcelProperty . 相對easyexcel,easypoi功能就相對單一點。
  • 兩者都可以在自身的功能不足的情況下,通過POI的功能實現自定義功能

easyexcel

  • easyexcel是重點物件。他基於註解的方式將以前POI的複雜的程式碼進模組抽離。我們基本上的需求只需要在excelproperty註解中就可以解決。
    - easyexcel最大的特點就是解決了記憶體洩漏的問題。以上幾種poi在匯出excel的時候都受到了資料的影響.而且效能上還不是很好。easyexcel是POI系列產品的最佳之選

快速入門

easyexcel名字非常的符合他的個性。他是真的很easy.下面我們來實現一個匯出學生資訊的程式碼


String fileName = EasyExcelTools.class.getResource("/").getPath() + "student" + System.currentTimeMillis() + ".xlsx";
ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(fileName, Student.class);
//excelWriterBuilder.registerConverter(new SexConverter()).registerWriteHandler(new AgeRowHandler()).registerWriteHandler(new SexCellWriteHandler());
ExcelWriter excelWriter = excelWriterBuilder.build();
WriteSheet writeSheet = EasyExcel.writerSheet("中化安元").build();
try {
    excelWriter.write(ts, writeSheet);
} catch (Exception e) {
    e.printStackTrace();
}finally {
    excelWriter.finish();
}

程式碼解讀

  • Student是匯出需要的實體。裡面配置了表格的一些基本資訊
  • ts 是Student資料的一個集合
  • fileName 是匯出的檔案地址

    student


public class Student {

/**
  * 學生索引id
  */
@ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"學號"})
private String id;
/**
  * 姓名
  */
@ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"姓名"})
private String userName;

/**
  * 使用者暱稱
  */
@ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"暱稱"})
@ExcelIgnore
private String userNick;

/**
  * 年齡
  */
@ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"年齡"})
private Integer age;
/**
  * 性別 true : 男  ; false : 女
  */
@ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"性別"})
private boolean sex;
/**
  * 生日
  */
@ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"生日"})
private Date birth;
/**
  * 身高
  */
@ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"身高"})
private Double height;

}

總結

  • 通過easyexcel匯出我們只需要準備好資料,然後兩行程式碼匯出。

常用API

  • EasyExcel 入口類,用於構建開始各種操作
  • ExcelReaderBuilder ExcelWriterBuilder 構建出一個 ReadWorkbook WriteWorkbook,可以理解成一個excel物件,一個excel只要構建一個
  • ExcelReaderSheetBuilder ExcelWriterSheetBuilder 構建出一個 ReadSheet WriteSheet物件,可以理解成excel裡面的一頁,每一頁都要構建一個
  • ReadListener 在每一行讀取完畢後都會呼叫ReadListener來處理資料
  • WriteHandler 在每一個操作包括建立單元格、建立表格等都會呼叫WriteHandler來處理資料
  • 所有配置都是繼承的,Workbook的配置會被Sheet繼承,所以在用EasyExcel設定引數的時候,在EasyExcel...sheet()方法之前作用域是整個sheet,之後針對單個sheet

單元格樣式

  • 因為被封裝了一層。如果easyexcel滿足不了我們的話,我們可以通過workbook去具體操作單元格內容和樣式。這種方法是萬不得已在使用。就比如我們想改變單元格樣式。easyexcel提供了開發介面CellWriteHandler。我們只需要實現這個介面並重寫他的beforeCellCreateafterCellCreateafterCellDispose.其中afterCellDispose方法是在單元格建立後銷燬前的一個時機。這時候我們可以改變單元格內容。easyExcel提供了四種時間捕捉介面
    CellWriteHandler
    WorkbookWriteHandler
    SheetWriteHandler
    RowWriteHandler

合併單元格

  • 在POI中我們實現合併單元格我們需要指定合併的範圍。但是在easyexcel中我們只需要在ExcelProperty註解中加入表頭的時候在對應位置加入相同的內容就會自動的合併單元格。


資料樣式

  • 資料樣式使我們Java開發中經常遇到的。比如說學生資訊中的性別我們粗在資料庫中大部分情況都是通過0、1來控制的。但是我們匯出的時候肯定是不能直接展示01的。這個時候我們就需要資料樣式了。說的在明白點就是資料格式轉換。在easyexcel中提供了Converter介面。
    convertToJavaData : excel資料轉換成Java物件
    convertToExcelData: Java物件轉換成excel資料

多sheet設定

  • 多sheet頁實際上就是建立多個sheet。每個sheet有不同的編號。剩下的操作都是一樣的。

單元格新增超連結

  • 通過CellWriteHandler實現在afterCellDispose方法中實現
CreationHelper createHelper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper();
Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL);
hyperlink.setAddress("https://gitee.com/zxhTom");
cell.setHyperlink(hyperlink);

依賴


<dependency>
   <groupId>net.sourceforge.javacsv</groupId>
   <artifactId>javacsv</artifactId>
   <version>2.0</version>
</dependency>

使用版本


<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.1.0-beta4</version>
</dependency>

中流砥柱

  • ExcelProperty: 實體屬性配置註解
  • BaseRowModel : 編寫實體繼承的實體類
  • WriteHandler : 用來控制單元格輸出,包括樣式和資料格式設定
  • ExcelWriter : 用於匯出excel

notes

系統時間

1900 windowing 1900年日期系統
1904 windowing 1904年日期系統
Excel for windows 使用1900
Excel2008 for mac 和之前版本 1904
excel 2016 for mac ; excel for mac 2011 1900

讀寫資料格式內建轉換器

  • BigDecimalBooleanConverter()
  • BigDecimalNumberConverter();
  • BigDecimalStringConverter();
  • BooleanBooleanConverter();
  • BooleanNumberConverter();
  • BooleanStringConverter();
  • ByteBooleanConverter();
  • ByteNumberConverter();
  • ByteStringConverter();
  • DateNumberConverter();
  • DateStringConverter();
  • DoubleBooleanConverter();
  • DoubleNumberConverter();
  • DoubleStringConverter();
  • FloatBooleanConverter();
  • FloatNumberConverter();
  • FloatStringConverter();
  • IntegerBooleanConverter();
  • IntegerNumberConverter();
  • IntegerStringConverter();
  • LongBooleanConverter();
  • LongNumberConverter();
  • LongStringConverter();
  • ShortBooleanConverter();
  • ShortNumberConverter(Converter 資料轉換介面);
  • ShortStringConverter();
  • StringBooleanConverter();
  • StringNumberConverter();
  • StringStringConverter();
  • StringErrorConverter();

ModelBuildEventListener

  • ModelBuildEventListener 預設的也是第一個資料監聽器,主要功能就是將讀取到的當前行資料轉換成實體或者map

write

  • FileUtils.createPoiFilesDirectory();
    在初始化時建立臨時快取目錄以避免POI併發寫入錯誤

讀寫流程分析

read

write

加入戰隊

# 加入戰隊

微信公眾號

相關推薦

excel技術分享

目錄 簡介 匯出excel常用的幾種方法 POI CSV jxl jxls easyexcel 快速入門 程式

34張IT架構師技術知識圖譜(轉)

1.1 架構師圖譜 1.2 Java架構師圖譜 1.3 微服務架構祕籍 1.4 一致性圖譜 1.5 網際網路大流量的方法 1.6 安全祕籍 1.7 阿里巴巴常用小框架 1.8 架構方法論圖譜 1.9 設計模式祕籍圖譜 二 2.1 JVM虛

34張IT架構師技術知識圖譜【只收藏不看系列】

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

【轉載】:TensorFlow 好玩的技術、應用和你不知道的黑科技

tube map 高性能 知識 seq 出現 執行時間 mes lex 【導讀】TensorFlow 在 2015 年年底一出現就受到了極大的關註,經過一年多的發展,已經成為了在機器學習、深度學習項目中最受歡迎的框架之一。自發布以來,TensorFlow 不斷在完善並增加新

程序員進階路上不能錯過的技術知識圖譜秘籍

容器 互聯網 def 1.3 java架構師 方法 分享 開發技能 2.4 今天在技術大海中遊啊遊遊啊遊,哇啊哈哈 ^_^發現了一份非常有用的超級技術圖譜誒! 強烈推薦啊!!本文原作者是易寶支付技術經理/架構師李艷鵬,這是鵬哥多年來積累和收集的技術知識技能圖譜,有的是鵬哥原

IT架構師絕對不能錯過的34張技術知識圖譜

技能圖譜架構師圖譜Java架構師圖譜微服務架構秘籍 一致性圖譜互聯網大流量的方法安全秘籍阿裏巴巴常用小框架架構方法論圖譜設計模式秘籍圖譜 JVM虛擬機垃圾回收圖譜Java並發圖譜Java集合圖譜Java集合類圖Java List類圖Java Map類圖Java Set類圖Java TCP IPHadoop技能

【重磅來襲:系列二】NB-IoT技術方面的系列問題和聯盟答案

zdb 史上最全 post lnl gyb nb-iot技術 dsd cxx target 1p賀新艙jp蔔裝鏈5f杖家醞http://bgjxld.wikidot.com/nv涯匱巴zt凹舷感9a溫悠舊http://zmzjsz.wikidot.com/lx猶鍁匭3d拭謨

Istio技術與實踐06:!Istio安裝引數介紹

一、 CertManage Istio-1.0版本新加入的元件,利用ACME為Istio簽發證書 Key Default Value Description certmanager.enabled TRUE

《Java工程師技術+生活書籍吐血整理推薦技術書pdf》已拿BAT,網易,頭條Offer大佬力薦

       前言:Java開發工程師一般負責後端開發,當然也有專門做Java Web的工程師,但是隨著前後端的分離,越來越多的Java工程師需要往大後端方向發展。今天我們就來介紹一下Java後端開發者的書單。首先要感謝一下某大佬力推的後端書架,初學階段讀到了很多好書直

專案管理學習總結(9)——網際網路八大技術崗位詳解

網際網路技術崗位詳解,涉及到前段開發、後端開發、移動端開發、大資料、專案管理、測試、運維、技術管理等八大領域。架構師每個產品線都有架構師,在技術平臺部門也需要技術平臺的架構師。架構師負責設計系統整體架構,從需求到設計的每個細節都要考慮到,把握整個專案,使設計的專案儘量效率高,

!阿里智慧人機互動的核心技術解析

“連線“本身不是目的,它只是為“互動”建立了通道。在人機互動(Human-Computer Interaction)中,人通過輸入裝置給機器輸入相關訊號,這些訊號包括語音、文字、影象、觸控等中的一種模態或多種模態,機器通過輸出或顯示裝置給人提供相關反饋訊號。“連線”為

: svn與git的對照(二):svn與git的相關概念

fill 來看 out avi head clas 相關 iss b2c 如圖1是svnserver端數據的文件夾結構 以下是gitserver端的文件夾結構 縱觀svn和git服務端的文件夾結構我們非常easy發現 1.有些目錄還是蠻像的。甚

React Native常用第三方組件匯總-- 之一

提示 存儲 ext upload body ner board pup wan 把我認為最好的知識,拿來與他人分享,是這一生快事之一! React Native 項目常用第三方組件匯總: react-native-animatable 動畫 react-na

掛載文件系統出現"kernel panic..." 解決方案

某個文件 table sha mount nic mic 2.6 完成 又是   問:掛載自己制作的文件系統卡在這裏:    NET: Registered protocol family 1    NET: Registered protocol family 17   

的Ajax

tool 復制 last 毫秒 如何實現 mon adding ast turn 本章內容: 簡介 偽 AJAX 原生 AJAX XmlHttpRequest 的屬性、方法、跨瀏覽器支持 jQuery AJAX 常用方法 跨域 AJAX JsonP

oracle表空間查詢維護命令大全之中的一個(數據表空間)

ava 劃分 man max rac 帳戶 oca nio msi 表空間是數據庫的邏輯劃分,一個表空間僅僅能屬於一個數據庫。全部的數據庫對象都存放在建立指定的表空間中。但主要存放的是表, 所以稱作表空間。在oracle 數據庫中至少存在

的變量、作用域和內存問題

分配 data () pen ole 創建 最全 操作符 釋放內存 (一)JavaScript變量能夠用來保存兩種類型的值:基本類型值和引用類型值。基本類型的值源自下面5種基本數據類型:Undefined、Null、Boolean、Number和 Str

Html和CSS布局技巧

喜歡 輸出 隔離 init scale ext med 兩種 float 單列布局水平居中 水平居中的頁面布局中最為常見的一種布局形式,多出現於標題,以及內容區域的組織形式,下面介紹四種實現水平居中的方法(註:下面各個實例中實現的是child元素的對齊操作,child元素的

轉: 作者 李艷鵬: 的架構師圖譜

-s -a ddd java se http 聯網 hadoop -c clas 本文是筆者多年來積累和收集的知識技能圖譜,有的是筆者原創總結的最佳實踐,有的是小夥伴們的分享,其中每個秘籍圖譜裏面的內容都是互聯網高並發架構師應該了解和掌握的知識,筆者索性把這些圖譜收集在

正確的zabbix server安裝過程

zabbix安裝 zabbix server 說在前面的話:本例使用的是centos7、zabbix2.2.6版本,其他版本需要再驗證不要使用yum安裝tomcat和jdk,否則安裝zabbix會報錯正文:一、Lamp安裝及準備工作yum -y install httpd mysql mysql-se