沒想到啊,Java操作Excel竟然這麼簡單!

2021-03-02 JAVA葵花寶典
前言

在工作中,使用excel表格處理數據是很常見的操作,本文就來講解下如何使用開源輪子實現下載、導入、導出的功能。

在之前,很多Java程式設計師都喜歡使用POI的類庫來操作excel,但是非常的不方便,不僅代碼寫的很臃腫,還要處理各種office版本兼容問題,最怕的就是使用不當很容易造成內存溢出,因此今天給大家推薦阿里的一款開源項目 easyexcel。

項目介紹

easyexcel是一款快速、簡單避免OOM的java處理Excel工具

github地址:https://github.com/alibaba/easyexcel

Start:15.2k

看了下,兩天前項目團隊還有在完善代碼,可見項目還是挺活躍的

image-20200611173444558項目集成

使用idea開發工具簡單創建了一個easyexcel-demo項目,加入了web模塊以及easyexcel maven依賴,依賴如下:

<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.4</version>
</dependency>

版本的話我們使用2.2.4,2020年6月份上傳的,算是最新的版本了。

image-20200611174114531

好了,我們就開始寫功能了。

1、實現已有Excel模板下載

很多系統有數據批量導入的場景,因為在頁面上批量加數據時間成本太大了,但是一般導入的時候得按照一定的格式改,所以一般好的產品會先讓用戶下載一個帶有格式的文檔,然後按照格式寫好以後上傳導入,我們來實現這個功能吧!

創建模板文件

首先我們創建一個模板文件,內容如圖

image-20200611175645484

###將模板文件放置再項目裡

然後我們把它放在項目的配置文件下,如圖

image-20200611184415028

然後下載代碼也很簡單,主要分為加載資源->讀取資源->寫入響應流

@RestController
@RequestMapping("/user")
public class UserController {
    /**
     * 下載模板
     */
    @GetMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response) throws Exception {
        ClassPathResource classPathResource = new ClassPathResource("excelTemplate/easyexcel.xlsx");
        InputStream inputStream = classPathResource.getInputStream();
        Workbook workbook = new HSSFWorkbook(inputStream);
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode("easyexcel.xlsx", "utf-8"));
        response.setHeader("Access-Control-Expose-Headers", "content-Disposition");
        OutputStream outputStream = response.getOutputStream();
        workbook.write(outputStream);
        outputStream.flush();
        outputStream.close();
    }
}

測試

啟動項目,訪問,如圖所示,可以下載。

Jun-11-2020 18-41-522.寫入數據並生成文件

將數據導出到文檔這種場景可以說是最常見的了,那麼怎麼使用easyExcel快速實現呢,我們同樣還是以上面的模板為例

定義模型映射對象 UserExcelModel
@Data
public class UserExcelModel  extends BaseRowModel implements Serializable {

    @ExcelProperty(value = "用戶名", index = 0)
    private String name;

    @ExcelProperty(value = "年齡", index = 1)
    private Integer age;

    @ExcelProperty(value = "手機號", index = 2)
    private String mobile;

    @ExcelProperty(value = "性別", index = 3)
    private String sex;
}

定義這個對象的目的有兩個:當前場景下寫入文件作為model對象構造數據以及下個要講的數據讀取了。

「簡要代碼流程如下:」

定義列標題->創建sheet->自定義字體和風格->構造數據->寫入數據->寫入到瀏覽器響應流

 /**
     * 導出數據
     */
    @GetMapping("/exportData")
    public void exportData(HttpServletResponse response) throws Exception {
        XSSFWorkbook workbook = new XSSFWorkbook();

        String []columnNames = {"用戶名","年齡","手機號","性別"};

        Sheet sheet = workbook.createSheet();
        Font titleFont = workbook.createFont();
        titleFont.setFontName("simsun");
        titleFont.setBold(true);
        titleFont.setColor(IndexedColors.BLACK.index);

        XSSFCellStyle titleStyle = workbook.createCellStyle();
        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
        titleStyle.setFont(titleFont);

        Row titleRow = sheet.createRow(0);

        for (int i = 0; i < columnNames.length; i++) {
            Cell cell = titleRow.createCell(i);
            cell.setCellValue(columnNames[i]);
            cell.setCellStyle(titleStyle);
        }
        //模擬構造數據
        List<UserExcelModel> dataList = new ArrayList<>();
        dataList.add(new UserExcelModel("張三",12,"13867098765","男"));
        dataList.add(new UserExcelModel("張三1",12,"13867098765","男"));
        dataList.add(new UserExcelModel("張三2",12,"13867098765","男"));
        dataList.add(new UserExcelModel("張三3",12,"13867098765","男"));

        //創建數據行並寫入值
        for (int j = 0; j < dataList.size(); j++) {
            UserExcelModel userExcelModel = dataList.get(j);
            int lastRowNum = sheet.getLastRowNum();
            Row dataRow = sheet.createRow(lastRowNum + 1);
            dataRow.createCell(0).setCellValue(userExcelModel.getName());
            dataRow.createCell(1).setCellValue(userExcelModel.getAge());
            dataRow.createCell(2).setCellValue(userExcelModel.getMobile());
            dataRow.createCell(3).setCellValue(userExcelModel.getSex());
        }
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode("easyexcel.xls", "utf-8"));
        response.setHeader("Access-Control-Expose-Headers", "content-Disposition");
        OutputStream outputStream = response.getOutputStream();
        workbook.write(outputStream);
        outputStream.flush();
        outputStream.close();
    }


3.讀取數據image-20200619140427117

我們再回過頭來看我們定義的這個Model對象,通過指定index可以對應讀取的excel裡面的列,然後定義的數據類型就對應到excel裡面具體的值,來看看如何實現:

    @PostMapping("/readExcel")
    public List<UserExcelModel> readExcel(@RequestParam("file") MultipartFile file){
        List<UserExcelModel> list = new ArrayList<>();
        try {
            list = EasyExcel.read(file.getInputStream(),UserExcelModel.class,new ModelExcelListener()).sheet().doReadSync();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

看完代碼是不是心裡一萬頭草擬嗎飛過~ 看完這個代碼再看用poi工具處理的,是不是相當簡潔了。對於代碼中的ModelExcelListener,其實是我們自定義的一個讀取監聽類,貼貼代碼:

public static class ModelExcelListener extends AnalysisEventListener {
        private List<Object> datas = new ArrayList<>();
        /**
         * 通過 AnalysisContext 對象還可以獲取當前 sheet,當前行等數據
         */
        @Override
        public void invoke(Object data, AnalysisContext context) {
            //數據存儲到list,供批量處理,或後續自己業務邏輯處理。
            log.info("讀取到數據{}",data);
            datas.add(data);
            //根據業務自行處理,可以寫入資料庫等等
        }

        //所以的數據解析完了調用
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            log.info("所有數據解析完成");
        }
    }

這是一個讀取數據監聽類,有特殊業務需求的都可以在這個類裡面自定義實現,比如邊讀邊寫庫啊,數據過濾和處理等等,用的好了絕對是一把利劍。

PostMan模擬調用image-20200619145720559控制臺輸出image-20200619145829105總結

通過本篇文章,我們演示了如何使用easyexcel進行一些excel的操作,在實際的項目應用中,可以對以上示例代碼進行進一步的封裝,使其不管是讀取、導出等操作都能幾行代碼搞定,這個就得根據情況大家自由發揮了。

項目代碼獲取

地址:https://github.com/pengziliu/GitHub-code-practice/ 

點擊底部閱讀原文


已擼完部分開源輪子,更多精彩正在路上

模塊所屬開源項目項目介紹springboot_api_encryptionrsa-encrypt-body-spring-bootSpring Boot接口加密,可以對返回值、參數值通過註解的方式自動加解密 。simpleimage-demosimpleimage圖片處理工具類,具有加水印、壓縮、裁切等功能xxl-job-demoxxl-job分布式定時任務使用場景xxl-sso-demoxxl-sso單點登錄功能vuepress-demovuepress建立自己的知識檔案庫xxl-conf-demoxxl-conf分布式配置中心Shardingsphere-demoShardingsphere分庫分表easyexcel-demoeasyexcelexcel操作工具類
喜歡做關注做個標記唄。點個再看,發文第一時間知道~

相關焦點

  • Java如何操作Word, Excel, PDF文檔?
    參考:  http://danadler.com/jacob/  http://jakarta.apache.org/poi/  http://www.onjava.com/pub/a/onjava/2003/01/22/poi.html  http://www.csdn.net/develop/article/15/15311
  • 每日一課 | Apache POI –用Java讀寫Excel文件
    HSSF在類名之前添加前綴,以指示與Microsoft Excel 2003文件相關的操作。XSSF在類名之前添加前綴,以指示與Microsoft Excel 2007文件或更高版本相關的操作。Apache POI庫–編寫簡單的Excel以下代碼顯示了如何使用Apache POI庫編寫一個簡單的Excel文件。該代碼使用二維數據數組來保存數據。數據被寫入XSSFWorkbook對象。XSSFSheet是正在處理的工作表。
  • 萬萬沒想到!這幾個excel技巧這麼好用!
    Excel作為我們辦公必不可少的辦公軟體,想要學好,並成為一個大神,是有點困難的,因為它擁有複雜的函數公式,多樣的辦公處理工具,所以,想要學好excel,還是有一些難度的。但如果是想要慢慢積累excel技巧,慢慢成為一個excel大神的話,這成功的機率還是比較大的。
  • Hutool Java 工具類庫導出 Excel,超級簡單!
    以前用過POI、easyexcel等工具的導入導出功能,但總感覺太麻煩了,代碼特別多,感覺並不是很好用。今天給大家介紹一款新工具,java工具類庫Hutool。writer.merge(2, "申請人員信息"); // 一次性寫出內容,使用默認樣式,強制輸出標題 writer.write(list, true); //out為OutputStream,需要寫出到的目標流 //response為HttpServletResponse對象 response.setContentType("application/vnd.ms-excel
  • 牛逼的EasyExcel,讓Excel導入導出更加簡單,附詳細教程!
    可以看出只需要在實體對象使用@ExcelProperty註解,讀取時指定該class,即可讀取,並且自動過濾了空行,對於excel的讀取及其簡單。// 這個轉換是成全局的, 所有java為string,excel為string的都會用這個轉換器。
  • 程式設計師:java導出Excel,附帶依賴、後端代碼和前端JS
    -- 解析Excel文件的jar包 用於2007+ 版本的excel --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId
  • 幾種流行小吃的做法,沒想到竟然這麼簡單
    幾種流行小吃的做法,沒想到竟然這麼簡單第1種呢就是香煎土豆,它的做法是非常的簡單的,先把土豆切成塊,煮熟之後再把小蔥切成末,鍋裡面放入適量的油,將煮熟的土豆控一下水分之後放進去,中小火煎,煎到每一面都有鍋巴之後再加入孜然粉,孜然粒,鹽,黑胡椒粉
  • 手感打擊感都很好,令我沒想到的是音遊劇情竟然還這麼完整
    每首曲子有簡單困難chaos三個難度。萌新入坑摸索了一個多小時,就能最低要求過chaos了。第二,選曲全面而精緻。幾個不同的遊戲主角的曲子都是不同類型的。比如Neko的日系死宅向音樂,蘿蔔頭的EDM等等。(一些音樂包和主角需要付費解鎖,不過個人感覺物所超值,曲子都超讚的!)第三,劇情設計很特別。怎麼說呢,感覺玩了這個遊戲後,在下都有點感覺遊戲主角真實存在於我們的世界了。
  • 程序汪幫公司面試3年1萬8的Java程式設計師,基礎的問題沒回答好啊
    ,但是高級就不行了,只少給面試官說一個相對複雜點的場景吧並發多線程場景,這是加分項,spring線程池怎麼用啊,多線程什麼場景裡用啊,說的非常清楚,必須加分第三方接口調用,如調用銀行接口,裡面關於異常怎麼定義啊,失敗機制、重試機制、冪等機制,說清楚就是加分代碼的優雅設計,項目中用了模板啊、單例、高級泛型啊、異常設計、日誌啊、攔截器啊、自定義註解啊、枚舉高級特性啊
  • 我是一個Java class
    java.lang.String 難得的悠閒, 端著一杯咖啡一邊看我手忙腳亂的取指令, 一邊說:"新人都這樣, 別著急,等你熟練了,閉著眼睛就搞定了, 就像我一樣,你可能不知道 , 我們這個虛擬機叫做基於堆棧的虛擬機, 看到那個桶沒有,其實就是個先進後出的棧啊, 我們虛擬機的所有指令其實都是在對棧進行操作"可是我還是好奇: 「這棧有什麼好啊」旁邊的格子間的ja
  • SpringBoot搭配EasyExcel,一切表格就這麼完美解決了~
    作者:GreenCode出處:https://www.cnblogs.com/nayou/p/13896456.html正文如下:# 概述EasyExcel是一個基於Java的簡單response.setCharacterEncoding("utf-8"); String fileName = "學生通行記錄" + DateUtils.getDate("yyyy-MM-dd HH:mm") + ".xlsx"; response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode
  • 沒想到三明治不放沙拉醬,口感竟然也這麼好吃!
    沒想到三明治不放沙拉醬,口感竟然也這麼好吃!我想,對於正在減脂期間的人來說,「吃什麼」似乎成為了減肥達人最頭疼的問題了吧!好了,說了這麼多,小編就是想用自己的親身經歷告訴想要減肥的朋友們,胖子不是一口吃出來的,想瘦下去也要量力而行,慢慢來。最重要的是不要以減肥的目的去損害自己的健康。會吃才會瘦!
  • Python讀寫Excel表格,就是這麼簡單粗暴又好用
    python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。可從這裡下載https://pypi.python.org/pypi。下面分別記錄python讀和寫excel。
  • 後端:Hutool Java 工具類庫導出 Excel,超級簡單!
    以前用過POI、easyexcel等工具的導入導出功能,但總感覺太麻煩了,代碼特別多,感覺並不是很好用。今天給大家介紹一款新工具,java工具類庫Hutool。writer.merge(2, "申請人員信息"); // 一次性寫出內容,使用默認樣式,強制輸出標題 writer.write(list, true); //out為OutputStream,需要寫出到的目標流 //response為HttpServletResponse對象 response.setContentType("application/vnd.ms-excel
  • 減脂運動排行榜-沒想到第一名竟然這麼簡單!
    01-跳繩消耗熱量:93.3大卡/10分鐘沒想到吧!跳繩竟然是減脂運動排行榜的榜首。它是一項可以鍛鍊到全身肌肉的運動項目,尤其針對臀部和大腿上的多餘贅肉,還可以塑造手臂線條,熱量消耗不容小覷。
  • 大神詳解,這麼詳細的Java設計模式不收藏可惜了
    對於我來說,設計模式始於java,不止於java。第三,有了這種規範,可以更好的和他人溝通,言簡意賅。1.簡單工廠模式這個用的比較少,就是有個工廠,告訴你我要什麼東西,你造好了給我就行。比如說:9.橋接模式就是用於抽象化和實現化的解耦。又是解耦,貌似設計模式就是教我們如何優雅的解耦。
  • 驚,Java 字符串拼接竟然有這麼多玩法!| CSDN 原力計劃
    到底為什麼啊,我平常一直就用的『+』號操作符啊!二哥有空的時候能否寫一篇文章分析一下呢?我當時看到這條微信的第一感覺是:小菜你也太菜了吧,這都不知道為啥啊!我估計正在讀這篇文章的你也會有同樣的感覺。但捫心自問,在我做程式設計師的前兩年內,我也不知道為啥。遇到字符串拼接就上「+」號操作符,甭管是不是在循環體內。和小菜比起來,我當時可沒他這麼幸運,還有一位熱心的「二哥」能夠分享這份價值連城的開發手冊。
  • Python3操作excel的集大成者pandas
    有個Python開發包的大管家,名叫Anaconda,這傢伙安裝好後,就有了操作excel的開發包pandas,既然用Anaconda的挺多,想必處理excel時,他們會更多選擇用pandas,而它是基於NumPy 的一種工具,該工具是為了解決數據分析任務而創建的。
  • 微信好友怎麼導出excel?微信導出原來這麼簡單
    微信好友怎麼導出excel?微信導出原來這麼簡單 2020年01月19日 15:00作者:黃頁編輯:黃頁 微信好友怎麼導出
  • 「Excel實用技巧」沒想到吧!Excel中插入圖片竟然還有這麼多玩法
    在表格中插入圖片是我們經常遇到的,那你知道如何操作才能使你的圖片固定到表格裡嗎?如何快速連結到圖片?本期幫主與大家分享的有關圖片的一些操作。1、圖片怎麼固定到單元格中?1)點擊【插入】選項卡,選擇圖片,之後選擇你所需要的圖片,然後將圖片移到合適的位置2)選中圖片,右擊設置【大小和屬性】,找到【屬性】,勾選【隨單元格改變位置和大小】3)設置好之後不論是添加行列還是刪除,圖片都會跟隨單元格而變化具體操作如下