花了 5 分鐘就搞定了 Java 下載和解析 Excel

2021-02-14 imooc編程手記

工欲善其事必先利其器,果然有道理,之前經常做一些 Excel 的解析和寫入,大家估計也對 jxl 和 poi 有所耳聞,操作起來那是一塌糊塗,需要了解裡面的各種變量,然而這次我們使用的是阿里開源的 EasyExcel,5分鐘搞定下載和上傳解析。

我們寫代碼之前先說一下我們模擬的場景,我們需要使用 EasyExcel 實現文章的批量上傳和下載。

話不多說直接上代碼,文末可以獲取全部代碼。代碼運行的環境是 Spring Boot,所以具體的 Spring Boot 搭建細節我們就不說了,直接從引入 EasyExcel 開始。

1. 引入依賴
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.4</version>
</dependency>

2. 下載模板

如果需要上傳 Excel,勢必需要提前準備好模板,那麼這點 EasyExcel 做的更簡潔,我們直接上代碼。定義一個 download 請求,設置  application/vnd.ms-excel 為了返回內容後直接可以作為 excel 文件下載。下面才是重點。

EasyExcel.write 是設置具體需要映射的對象到返回的流EasyExcel.sheet 設置具體的 sheet 名字EasyExcel.doWrite 寫入具體的內容,也是 write 裡面對應的 Article 對象的列表。
EasyExcel
  .write(response.getOutputStream(), Article.class)
  .sheet("模板")
  .doWrite(new ArrayList());

@GetMapping("tempalte")
public void tempalte(HttpServletResponse response) throws IOException {
    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("utf-8");
    String fileName = URLEncoder.encode("文章模板", "UTF-8");
    response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    EasyExcel.write(response.getOutputStream(), Article.class).sheet("模板").doWrite(new ArrayList());
}

Article.java 類,裡面就比較簡單了,定義了三個屬性,這三個屬性分別通過 ExcelProperty 映射 Excel 的標題,也就是列,一定要有 setter 和 getter 方法,這裡為了依賴少直接生成的,你也可以使用 Lombok。

public class Article {
    @ExcelProperty("文章標題")
    private String title;
    @ExcelProperty("文章連結")
    private String link;
    @ExcelProperty("閱讀數")
    private Integer view;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getLink() {
        return link;
    }

    public void setLink(String link) {
        this.link = link;
    }

    public Integer getView() {
        return view;
    }

    public void setView(Integer view) {
        this.view = view;
    }
}

接下來我們運行程序EasyExcelApplication(源碼中的啟動類),然後訪問

http://localhost:8080/tempalte

神奇的一幕出現了,直接下載下來了一個 excel 文件,內容如下,是不是太簡單了?

上傳

根據剛剛下載的模板,把我事先準備好的文章錄入

然後定義一個接口 upload 如下,內容也是非常簡練,使用 EasyExcel.read 方法就可以搞定,其中 file.getInputStream() 是對應的文件輸入流,Article.class 就是剛才我們下載時候定義好的類,因為類型一樣,可以直接復用,ArticleReadListener 就比較重要了,它是用來接收所有解析行。其他的都是固定寫法。

@PostMapping("upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
    EasyExcel.read(file.getInputStream(), Article.class, new ArticleReadListener(articleDao)).sheet().doRead();
    return "success";
}

ArticleReadListener 需要注意的地方是我不能託管給 Spring 所以需要在構造方法裡面把預先注入的 articleDao 寫進入,articleDao 是為了模擬資料庫操作,為我們稍後的下載提供數據支持。

ArticleReadListener 相對來說也是非常簡單,先實現AnalysisEventListener類並傳入泛型 Article,複寫 invoke 方法解析的每一行 excel,因為傳入了泛型,會自動轉換為 Article,當然它會自動過濾標題行,所以正式解析的就是第一行內容,doAfterAllAnalysed 是讀取完所有內容以後的操作,我們調用 articleDao.save(raws); 把所有解析的內容存入 mock 的資料庫。

public class ArticleReadListener extends AnalysisEventListener<Article> {
    private ArticleDao articleDao;

    public ArticleReadListener(ArticleDao articleDao) {
        this.articleDao = articleDao;
    }

    private static final Logger logger = LoggerFactory.getLogger(ArticleReadListener.class);
    private List<Article> raws = new ArrayList<>();

    @Override
    public void invoke(Article data, AnalysisContext context) {
        logger.info("開始讀取文章:{}", JSON.toJSONString(data));
        raws.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        logger.info("一共讀取了{}篇文章,標題分別是:", raws.size(), raws.stream().map(Article::getTitle).collect(Collectors.toList()));
        articleDao.save(raws);
    }
}

ArticleDao 代碼不需要解釋,直接看下

@Service
public class ArticleDao {
    private List<Article> articles = new ArrayList<>();

    public void save(List<Article> raws) {
        articles = raws;
    }

    public List<Article> list() {
        return articles;
    }
}

然後直接使用 Postman 上傳文件

就可以在控制臺直接看到日誌內容了

開始讀取文章:{"link":"https://mp.weixin.qq.com/s/S0RCVJClS0094kjjmAn8yA","title":"讓人又愛又恨的 Lombok,到底該不該用","view":1378}
開始讀取文章:{"link":"https://mp.weixin.qq.com/s/r6toOIgrt4f9M8j4PGGaFQ","title":"Delombok 是個啥?居然可破 Lombok?","view":1559}
一共讀取了2篇文章,標題分別是:[讓人又愛又恨的 Lombok,到底該不該用, Delombok 是個啥?居然可破 Lombok?]

是不是非常簡單就讀取完了?那麼我們繼續完成下載

下載

你自己觀察可以看到,下載的代碼和下載模板的代碼基本一樣,唯一的不同.doWrite(articleDao.list()),把之前上傳存入資料庫的內容寫入 excel。

@GetMapping("download")
public void download(HttpServletResponse response) throws IOException {
    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("utf-8");
    String fileName = URLEncoder.encode("文章下載", "UTF-8");
    response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    EasyExcel
    .write(response.getOutputStream(), Article.class)
    .sheet("文章")
    .doWrite(articleDao.list());
}

話不多說,我們直接訪問 http://localhost:8080/download 看下結果,是不是非常簡單就可以完成上傳和下載?

完整代碼獲取地址
https://github.com/juice-resume/java-programming.git

相關焦點

  • 快速做一個Excel下載功能
    >1.0</version> </dependency>在springboot的配置文件application.properties上加上一行:# 是否解析帶有 @ResponseExcel 註解的函數的返回值為文件下載com.gaoice.easyexcel.enable-response-excel
  • 使用Java進行excel操作的幾種方法 (下)
    easyexcel是阿里巴巴開源的一款excel解析工具,底層邏輯也是基於apache poi進行二次開發的。不同的是,再讀寫數據的時候,採用sax模式一行一行解析,在並發量很大的情況下,依然能穩定運行!下面就一起來了解一下這款新起之秀!3.1 添加依賴包<!
  • Github上一個Java玩轉Excel的項目
    今天我們介紹一款超級簡單的Excel處理工具,EasyExcel,首先看一下官網介紹:Java解析、生成Excel比較有名的框架有Apache poi、jxl。easyexcel重寫了poi對07版Excel的解析,能夠原本一個3M的excel用POI sax依然需要100M左右內存降低到幾M,並且再大的excel不會出現內存溢出,03版依賴POI的sax模式。在上層做了模型轉換的封裝,讓使用者更加簡單方便
  • java如何處理excel文件?(附項目源碼)
    Excel被稱為使用最廣泛的數據分析軟體,它能夠和很多程式語言結合使用,例如java、R、c等常用語言。
  • 3分鐘,快速搞定excel數據輸入規範!(附帶筆記)
    原創不易-分享和點讚就是最好的鼓勵--留言告訴院長你日常的excel小難題-- 院 長 好 課 推 薦 -用5分鐘搞定1天的工作量10年數據名師手把手教你快速上手Excel其他同類課程/人,早鳥價99元/人每節不到5元,一個雪糕的價錢助你提高工作效率,挖掘數據本質成為核心員工學Excel,為什麼不向20000人都說好的老師學習?
  • 使用Java進行excel操作的幾種方法(上)
    導出操作,即使用Java寫出數據到Excel中,常見場景是將頁面上的數據導出,這些數據可能是財務數據,也可能是商品數據,生成Excel後返回給用戶下載文件。導入操作,即將excel中的數據採用java工具庫將其解析出來,進而將excel 數據寫入資料庫!
  • 用Java玩轉Excel,竟然如此easy~
    ,所以這裡就以excel方面來說明。的主要是HSSF和XSSF組件,前者針對97-2007的通用版excel,即後綴xls;後者針對2007或更高版的excel,即後綴xlsx。其下有兩個實現類:所以在針對不同版本的excel時,需要對應以上使用不同的Workbook。
  • 學透Excel函數,5分鐘搞定1天工作量
    簡單來說,同樣的數據處理和分析,別人一個星期的工作,如果你懂Excel,你一個小時就能解決。舉幾個簡單的慄子——慄子1:處理表格時,如何把名字首個字母全部變成大寫?輸入計算公式,3秒搞定!慄子2:統計業績時,如何讓1-4季度的總業績自動計算到匯總表?
  • 5 分鐘搞定 Java Comparable 接口
    在那樣的環境中,「小於」,「等於」和「大於」指的是什麼意思?也可以使用多個特徵,這個後面我們會講。例1:通過重量排序蘋果在第一個例子中,我們將通過重量對蘋果排序。只需要一行代碼。compareTo(Apple other) { if (this.weight < other.weight) { return -1; } if (this.weight == other.weight) { return 0; } return 1; }}例5
  • 每日一課 | Apache POI –用Java讀寫Excel文件
    XSSFWorkbook和HSSFWorkbook是充當Excel工作簿的類HSSFSheet和XSSFSheet是充當Excel工作表的類Row定義一個Excel行Cell定義參照行尋址的Excel單元格。
  • 乾貨 | 你花兩個小時做的Excel,那個實習生用VBA10分鐘就搞定了
    數據可視化?我可以!不但如此,數據透視表+VBA語言,還可以製作高大上的可視化分析和Dashboard儀錶盤,讓工作結果更加直觀。但是,主頁君想說,真的不需要花長時間去研究怎麼「精通VBA」!你只需要花上10-20%的精力,學會一些VBA基礎知識,就會感覺自己操作Excel的效率有翻天覆地的變化。小k就是按這個方法來入門,完成3天VBA闖關計劃,就學到了能夠直接上手的程度。
  • EasyExcel,讓 excel 導入導出更加簡單
    ExcelIgnore 默認所有欄位都會和excel去匹配,加了這個註解會忽略該欄位。DateTimeFormat 日期轉換,用String去接收excel日期格式的數據會調用這個註解。裡面的value參照java.text.SimpleDateFormat。NumberFormat 數字轉換,用String去接收excel數字格式的數據會調用這個註解。
  • JAVA連接HBase客戶端及HBase寫入數據和讀取數據原理解析
    _doit19.hbase.day01;import org.apache.hadoop.hbase.Cell;import org.apache.hadoop.hbase.CellUtil;import org.apache.hadoop.hbase.client.Put;import java.util.List;import java.util.Map;import java.util.NavigableMap
  • EasyExcel,讓excel導入導出更加簡單
    ExcelIgnore 默認所有欄位都會和excel去匹配,加了這個註解會忽略該欄位。DateTimeFormat 日期轉換,用String去接收excel日期格式的數據會調用這個註解。裡面的value參照java.text.SimpleDateFormat。NumberFormat 數字轉換,用String去接收excel數字格式的數據會調用這個註解。
  • PDF轉Office就這麼簡單,一步搞定
    只能轉五頁明明有同事就能三分鐘搞定,而你卻需要這麼久了?那是你沒有選對工具,要論PDF的轉換,沒有誰比Adobe更精通此事了,畢竟PDF就是Adobe家開發的文件格式,自然轉換起來也就容易的多了,也能更好的保留文件原來的格式。
  • 史上最快的10個Excel實用技巧,一秒搞定Excel
    圈兒有話說:今天分享10個速度超快的
  • 牛逼的EasyExcel,讓Excel導入導出更加簡單,附詳細教程!
    ExcelIgnore 默認所有欄位都會和excel去匹配,加了這個註解會忽略該欄位。DateTimeFormat 日期轉換,用String去接收excel日期格式的數據會調用這個註解。裡面的value參照java.text.SimpleDateFormat。NumberFormat 數字轉換,用String去接收excel數字格式的數據會調用這個註解。
  • Hutool Java 工具類庫導出 Excel,超級簡單!
    以前用過POI、easyexcel等工具的導入導出功能,但總感覺太麻煩了,代碼特別多,感覺並不是很好用。今天給大家介紹一款新工具,java工具類庫Hutool。Hutool中的工具方法來自於每個用戶的精雕細琢,它涵蓋了Java開發底層代碼中的方方面面,它既是大型項目開發中解決小問題的利器,也是小型項目中的效率擔當;Hutool是項目中「util」包友好的替代,它節省了開發人員對項目中公用類和公用工具方法的封裝時間,使開發專注於業務,同時可以最大限度的避免封裝不完善帶來的
  • 5分鐘搞定GSEA分析,你還怕什麼
    在某一項研究中,我們通過轉錄組或者蛋白組學研究了幹預組和對照組的表達譜,獲得了數千個基因的變化信息,如何從這些表達譜中發掘有用的信息?
  • 如何瀏覽器裡用js解析excel文件
    題圖 From 極客時間 By Clm上篇文章給大家介紹了如何藉助nodejs平臺解析操作excel,今天給大家介紹如何在瀏覽器端使用