亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于Java8實現(xiàn)提高Excel讀寫效率

 更新時間:2020年11月06日 11:12:26   作者:shuzihua  
這篇文章主要介紹了基于Java8實現(xiàn)提高Excel讀寫效率,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

在POI的使用過程中,對大多數API User來說經常面臨兩個問題,這也是GridExcel致力解決的問題。

問題1. 僅使用簡單的導入導出功能,但每次業(yè)務的數據對象結構不同,需要重新編寫處理方法,很麻煩!

解決方法

將Excel處理邏輯抽取出來,封裝成工具類。

封裝條件

與大多數Java API一樣,POI把更多的精力放在高級功能的處理上,比如Formula(公式)、Conditional Formatting(條件格式)、Zoom(縮放)等。對于僅僅做數據導入導出功能的API User,很少使用這些高級特性,這允許API用戶對POI的使用進行簡單的封裝。

封裝方式

無論是讀是寫,我們都需要解決Excel中的Columns(列)與Java數據對象Fields(字段)的映射關系,將這種映射關系作為參數(Map對象HashMap或LinkedHashMap),傳遞給工具類。

對于Columns不難理解,它可以是有序的數字或字母,也可以是其它字符串用來作為首行,表示該列數據的含義。

對于Fields,它的處理需要兼容復雜情況,如下:

  • 查詢字段時出現(xiàn)異常
  • 字段或單元格的值為null
  • 該列的值可能對應關聯(lián)對象、甚至是關聯(lián)集合中的某個字段值
  • 字段或單元格的值需要做特殊處理,例如value == true?完成:失敗;

反射

首先想到,也是大多數封裝者都在使用的方式是就是Reflection API,從上文 函數編程 章節(jié)我們了解到,反射重量級,會降低代碼的性能,同時對復雜情況的處理支持性不夠好。

反射+注解

這種方式可以更好的支持復雜情況,但是反射依然會降低性能,同時注解對數據對象會造成代碼侵入,而且對該工具類封裝者的其他使用者無疑會增加學習成本。

匿名內部類

這種方式也可以很好的支持復雜情況,但是使用匿名內部類的語法顯然患有“垂直問題”(這意味著代碼需要太多的線條來表達基本概念),太過冗雜。至于性能,應該也不如直接傳遞函數來的快吧。

函數接口(Lambda)

這種方式是基于第5條方法調用的字節(jié)碼指令invokeDynamic實現(xiàn)的,直接傳遞函數代碼塊,很好的支持復雜情況,性能較高,代碼編寫更簡單結構更加簡潔,而且對數據對象代碼零侵入。

當然如果你還沒有使用Java1.8或更高版本,那么你可以參考匿名內部類或反射+注解,不過還是推薦反射+注解,Alibaba/easyexcel【https://github.com/alibaba/easyexcel】對你來說會是不錯的選擇。

問題2. Excel導入或導出數據量比較大,造成內存溢出或頻繁的Full GC,該如何解決?

解決方法

  • 讀Excel —— eventmodel
  • 寫Excel —— streaming.SXSSFWorkbook

原理

POI的使用對我們來說很常見,對下面兩個概念應該并不陌生:

  • HSSFWorkbook(處理97(-2007) 的.xls)
  • XSSFWorkbook(處理2007 OOXML (.xlsx) )

但是對于eventmodel和streaming.SXSSFWorkbook就很少接觸了,它們是POI提供的專門用來解決內存占用問題的low level API(低級API),使用它們可以讀寫數據量非常大的Excel,同時可以避免內存溢出或頻繁的Full GC?!緃ttps://poi.apache.org/components/spreadsheet/how-to.html】

eventmodel,用來讀Excel,并沒有將Excel整個加載到內存中,而是允許用戶從InputStream每讀取一些信息,就交給回調函數或監(jiān)聽器,至于丟棄,存儲還是怎么處理這些內容,都交由用戶。

streaming.SXSSFWorkbook,用來寫Excel(是對XSSFWorkbook的封裝,僅支持.xlsx),通過滑動窗口來實現(xiàn),只在內存中保留滑動窗口允許存在的行數,超出的行Rows被寫出到臨時文件,當調用write(OutputStream stream)方法寫出內容時,再直接從臨時內存寫出到目標OutputStream。SXSSFWorkbook的使用會產生一些局限性。

  • Only a limited number of rows are accessible at a point in time.
  • Sheet.clone() is not supported.
  • Formula evaluation is not supported

解決途徑

https://github.com/liuhuagui/gridexcel 基于Java函數編程(Lambda),支持流式API,使用環(huán)境Java1.8或更高,學習成本:

Lambda

https://github.com/alibaba/easyexcel 基于反射+注解+監(jiān)聽器,使用環(huán)境Java1.6或以上,學習成本:模型注解
實際上POI官網已經給了用戶使用示例,而上述兩個工具都只是做了自己的封裝實現(xiàn),使用者只需要拿來用就好。

快速使用

<dependency>
  <groupId>com.github.liuhuagui</groupId>
  <artifactId>gridexcel</artifactId>
  <version>2.2</version>
</dependency>

GridExcel.java

GridExcel.java提供了多種靜態(tài)方法,可以直接使用,具體式例可參考測試代碼(提供了測試數據和測試文件):

https://github.com/liuhuagui/gridexcel/blob/master/src/test/java/ReadTest.java

https://github.com/liuhuagui/gridexcel/blob/master/src/test/java/WriteTest.java

流式API

/**
 * 業(yè)務邏輯處理方式三選一:
 * 1.啟用windowListener,并將業(yè)務邏輯放在該函數中。
 * 2.不啟用windowListener,使用get()方法取回全部數據集合,做后續(xù)處理。
 * 3.readFunction函數,直接放在函數中處理 或 使用final or effective final的局部變量存放這寫數據,做后續(xù)處理。
 * 注意:使用EventModel時readFunction函數的輸入為每行的cell值集合List<String>。
 * @throws Exception
 */
 @Test
 public void readXlsxByEventModel() throws Exception {
   InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("2007.xlsx");
   GridExcel.readByEventModel(resourceAsStream,TradeOrder.class,ExcelType.XLSX)
       .window(2,ts -> System.out.println(JSON.toJSONString(ts)))//推薦在這里執(zhí)行自己的業(yè)務邏輯
       .process(cs ->{
         TradeOrder tradeOrder = new TradeOrder();
         tradeOrder.setTradeOrderId(Long.valueOf(cs.get(0)));
         Consultant consultant = new Consultant();
         consultant.setConsultantName(cs.get(3));
         tradeOrder.setConsultant(consultant);
         tradeOrder.setPaymentRatio(cs.get(16));
         return tradeOrder;
       },1);
 }
 /**
 * 使用Streaming UserModel寫出數據到Excel
 * @throws Exception
 */
 @Test
 public void writeExcelByStreaming() throws Exception {
   GridExcel.writeByStreaming(TradeOrder.class)
       .head(writeFunctionMap())//對象字段到Excel列的映射
       .createSheet()
       .process(MockData.data())//模擬數據。在這里設置業(yè)務數據集合。
       .write(FileUtils.openOutputStream(new File("/excel/test.xlsx")));
 }

ReadExcel

ReadExcelByUserModel

Use user model to read excel file. userModel ——

缺點:內存消耗大,會將excel信息全部加載到內存再進行處理。

優(yōu)點:現(xiàn)成的API,使用和理解更簡單。

使用場景:可以處理數據量較小的Excel。

ReadExcelByEventModel

Use event model to read excel file. eventModel ——

缺點:沒有現(xiàn)成的API,使用和理解較為復雜,適合中高級程序員(GridExcel的目標之一就是讓EventModel的使用變得簡單)

優(yōu)點:非常小的內存占用,并沒有在一開始就將所有內容加載到內存中,而是把主體內容的處理(存儲,使用,丟棄)都交給了用戶,用戶可以自定義監(jiān)聽函數來處理這些內容。
使用場景:可以處理較大數據量的Excel,避免OOM和頻繁FullGC

WriteExcel

WriteExcelByUserModel

Use user model to write excel file. userModel ——

缺點:會將產生的spreadsheets對象整個保存在內存中,所以write Excel的大小受到堆內存(Heap space)大小限制。

優(yōu)點:使用和理解更簡單。

使用場景:可以寫出數據量較小的Excel。

WriteExcelByStreaming

Use API-compatible streaming extension of XSSF to write very large excel file. streaming userModel——

缺點:

  • 僅支持XSSF;
  • Sheet.clone() is not supported;
  • Formula evaluation is not supported;
  • Only a limited number of rows are accessible at a point in time.

優(yōu)點:通過滑動窗口來實現(xiàn),內存中只保留指定size of rows的內容,超出部分被寫出到臨時文件,write Excel的大小不再受到堆內存(Heap space)大小限制。

使用場景:可以寫出非常大的Excel。

Issues

在使用工具過程中出現(xiàn)問題,有功能添加或改動需求的可以向作者提Issue:https://github.com/liuhuagui/gridexcel/issues

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • java中BigDecimal和0比較的示例代碼

    java中BigDecimal和0比較的示例代碼

    這篇文章主要介紹了java中BigDecimal和0比較的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • java判斷域名無法訪問自行訪問下一條

    java判斷域名無法訪問自行訪問下一條

    這篇文章主要為大家介紹了java實現(xiàn)判斷域名無法訪問的時候自行訪問下一條域名示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • java中transient關鍵字分析

    java中transient關鍵字分析

    這篇文章主要介紹了java中transient關鍵字分析,transient與類對象的序列化息息相關,序列化保存的是 類對象 狀態(tài),被transient關鍵字修飾的成員變量,在類的實例化對象的序列化處理過程中會被忽略,變量不會貫穿對象的序列化和反序列化,需要的朋友可以參考下
    2023-09-09
  • java模擬cookie登陸操作

    java模擬cookie登陸操作

    這篇文章主要為大家詳細介紹了java模擬cookie登陸操作,模擬登陸,取得cookie以記錄身份,下次請求時發(fā)送cookie以表明身份,感興趣的小伙伴們可以參考一下
    2016-07-07
  • SpringBoot整合Flink CDC實現(xiàn)實時追蹤mysql數據變動

    SpringBoot整合Flink CDC實現(xiàn)實時追蹤mysql數據變動

    我們將整合Spring Boot和Apache Flink CDC(Change Data Capture)來實現(xiàn)實時數據追蹤,下面是一個基本的實踐流程代碼,包括搭建Spring Boot項目、整合Flink CDC以及實現(xiàn)數據變動的實時追蹤,需要的朋友可以參考下
    2024-07-07
  • 一文教你使用Java?Calendar類進行日期計算

    一文教你使用Java?Calendar類進行日期計算

    在日常開發(fā)中,我們常常需要進行日期計算,比如計算兩個日期之間的天數、月數,在Java中,我們可以使用Java?Calendar類來進行日期計算,下面就跟隨小編一起來學習一下吧
    2023-10-10
  • 詳解Servlet 3.0/3.1 中的異步處理

    詳解Servlet 3.0/3.1 中的異步處理

    這篇文章主要介紹了詳解Servlet 3.0/3.1 中的異步處理,實例分析了servlet 3.0異步處理的技巧,非常具有實用價值,需要的朋友可以參考下
    2017-04-04
  • MyBatis批量插入的三種方式比較總結

    MyBatis批量插入的三種方式比較總結

    由于項目需要生成多條數據,并保存到數據庫當中,所以就用到了MyBatis批量插入,下面這篇文章主要給大家介紹了關于MyBatis批量插入的三種方式的相關資料,需要的朋友可以參考下
    2021-08-08
  • MyBatis實現(xiàn)數據庫類型和Java類型的轉換

    MyBatis實現(xiàn)數據庫類型和Java類型的轉換

    MyBatis 在處理數據庫查詢結果或傳遞參數時,需要將數據庫類型與 Java 類型之間進行轉換,本文就給大家介紹MyBatis如何實現(xiàn)數據庫類型和 Java 類型的轉換的,需要的朋友可以參考下
    2024-09-09
  • 關于@PostConstruct、afterPropertiesSet和init-method的執(zhí)行順序

    關于@PostConstruct、afterPropertiesSet和init-method的執(zhí)行順序

    這篇文章主要介紹了關于@PostConstruct、afterPropertiesSet和init-method的執(zhí)行順序,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論