SpringBoot基於easyexcel導出和寫入Excel


 
easyexcel是阿里巴巴旗下開源項目,主要用於Excel文件的導入和導出處理,今天我們利用SpringBoot和easyexcel實戰演示如何導出和寫入Excel文件。

一、加入我們需要的easyexcel依賴

我們項目還用了其他依賴,我把我的pom文件全部貼在下面,讀者自行根據需要取舍

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.xu</groupId> <artifactId>easyexcel</artifactId> <version>0.0.1-SNAPSHOT</version> <name>easyexcel</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <swagger-ui.version>2.9.2</swagger-ui.version> <swagger2.version>2.9.2</swagger2.version> </properties> <dependencies> <!-- spring-boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- log related --> <dependency> <!-- exclude掉spring-boot的默認log配置 --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <!-- 表示開發的時候引入,發布的時候不會加載此包 --> <scope>test</scope> </dependency> <!-- mybatis-plus begin --> <!--mybatis-plus自動的維護了mybatis以及mybatis-spring的依賴,在springboot中這三者不能同時的出現,避免版本的沖突,表示:跳進過這個坑--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.0</version> </dependency> <!--swagger2--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${swagger-ui.version}</version> </dependency> <!--排除並新增1.5swagger-annotations和swagger-models 為了解決swagger2中example注解導致的input空字符串異常錯誤--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger2.version}</version> <exclusions> <exclusion> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> </exclusion> <exclusion> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> <version>1.5.21</version> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> <version>1.5.21</version> </dependency> <!-- 引入Druid依賴,阿里巴巴所提供的數據源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.29</version> </dependency> <!-- 提供mysql驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.16</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.46</version> </dependency> <!--熱部署--> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.8.RELEASE</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- alibaba的easyexcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>1.1.2-beta4</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 

二、定義我們的POJO

我們如果讀Excel文件或者寫入Excel,我們就需要先定義一個模型對應我們的Excel表格數據

package com.jwell.classifiedProtection.entry.excel;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import lombok.*;

/**
 * <p> * 系統 * </p> * * @author RonnieXu * @since 2019-08-02 */ @Data @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode(callSuper = false) public class UserExcelModel extends BaseRowModel { private static final long serialVersionUID = 1L; @ExcelProperty(value = "用戶名", index = 0) private String userName; @ExcelProperty(value = "密碼", index = 1) private String password; @ExcelProperty(value = "真實姓名", index = 2) private String realName; @ExcelProperty(value = "電話號碼", index = 3) private String phone; @ExcelProperty(value = "郵箱地址", index = 4) private String email; private String roleType; private Integer departmentId; private String remark; } 

三、定義我們的監聽器和導入導出方法

我們定義了一個導出導入工具類,這個類需要一個導入導出的監聽器,監聽器如下

package com.jwell.classifiedProtection.commons.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.BaseRowModel;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ExcelListener<T extends BaseRowModel> extends AnalysisEventListener<T> { private List<T> rows = new ArrayList<>(); /** * object是每一行數據映射的對象 * @param object * @param context */ @Override public void invoke(T object, AnalysisContext context) { System.out.println("當前行:"+context.getCurrentRowNum()); System.out.println(object); rows.add(object); //根據自己業務做處理 doSomething(object); } private void doSomething(T object) { //1、入庫調用接口 } @Override public void doAfterAllAnalysed(AnalysisContext context) { log.info("read {} rows %n", rows.size()); } public List<T> getRows() { return rows; } public void setRows(List<T> rows) { this.rows = rows; } } 

導入導出類ExcelUtils中有三個方法,導入方法、導出方法和下載方法導出文件方法【這個方法不需要的可以不用理會】

package com.jwell.classifiedProtection.commons.excel;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.jwell.classifiedProtection.entry.excel.UserExcelModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ExcelUtils {


    /**
     * @param is   導入文件輸入流
     * @param clazz Excel實體映射類
     * @return
     */
    public static <T extends BaseRowModel> List<T> readExcel(InputStream is, final Class<? extends BaseRowModel> clazz){ List<T> rowsList = null; BufferedInputStream bis = null; try { bis = new BufferedInputStream(is); // 解析每行結果在listener中處理 ExcelListener listener = new ExcelListener(); ExcelReader excelReader = EasyExcelFactory.getReader(bis, listener); excelReader.read(new Sheet(1, 1, clazz)); rowsList = listener.getRows(); } catch (Exception e) { e.printStackTrace(); return null; } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } } return rowsList; } /** * * @param os 文件輸出流 * @param clazz Excel實體映射類 * @param data 導出數據 * @return */ public static Boolean writeExcel(OutputStream os, Class clazz, List<? extends BaseRowModel> data){ BufferedOutputStream bos= null; try { bos = new BufferedOutputStream(os); ExcelWriter writer = new ExcelWriter(bos, ExcelTypeEnum.XLSX); //寫第一個sheet, sheet1 數據全是List<String> 無模型映射關系 Sheet sheet1 = new Sheet(1, 0,clazz); writer.write(data, sheet1); writer.finish(); } catch (Exception e) { e.printStackTrace(); return false; } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } return true; } /** * ResponseEntity下載文件 * * @param fileName * @param byteOutPutStream */ public static ResponseEntity<byte[]> downloadExcel(String fileName, ByteArrayOutputStream byteOutPutStream) { //下載文件 try { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); headers.setContentDispositionFormData("attachment", new String(fileName.getBytes("GBK"), "ISO8859-1"));// 文件名稱 ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(byteOutPutStream.toByteArray(), headers, HttpStatus.CREATED); return responseEntity; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 這是你最熟悉的老朋友Main方法,哈哈哈 * @param args */ public static void main(String[] args) { //1.導入Excel FileInputStream fis = null; try { fis = new FileInputStream("c:\\test\\test1.xls"); List<UserExcelModel> userExcelModelList = ExcelUtils.readExcel(fis, UserExcelModel.class); System.out.println("導入是否成功:-------------->"+"數據行數是:"+userExcelModelList.size()); } catch (FileNotFoundException e) { e.printStackTrace(); }finally { if (fis != null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } //2.導出Excel FileOutputStream fos = null; try { fos = new FileOutputStream("D:\\export.xlsx"); //FileOutputStream fos, Class clazz, List<? extends BaseRowModel> data List<UserExcelModel> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { UserExcelModel excelEntity = new UserExcelModel(); excelEntity.setUserName("我是名字" + i); list.add(excelEntity); } Boolean flag = ExcelUtils.writeExcel(fos, UserExcelModel.class, list); System.out.println("導出是否成功:" + flag); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } 

四、測試導入和導出【下載導出的Excel文件】

1、導入測試

新建一個Excel文件,我的文件路徑是c:\\test\\test1.xlsx

我的controller方法如下

package com.xu.easyexcel.controller;

import com.xu.easyexcel.commons.excel.ExcelUtils;
import com.xu.easyexcel.pojo.User;
import com.xu.easyexcel.pojo.excel.UserExcelModel;
import com.xu.easyexcel.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p> * 整改建議詳情列表詳情列表 前端控制器 * </p> * * @author RonnieXu * @since 2019-08-29 */ @Slf4j @Transactional(rollbackFor = Exception.class) @Api(value = "用戶接口", tags = "用戶接口") @RestController @RequestMapping("/user") public class UserController { @Autowired private IUserService iUserService; @ApiOperation(value = "導入Excel表格", notes = "導入Excel表格") @RequestMapping(value = "/readExcel", method = RequestMethod.POST) public void readExcelModel() { try{ FileInputStream inputStream = new FileInputStream("c:\\test\\test1.xlsx"); List<UserExcelModel> list = ExcelUtils.readExcel(new BufferedInputStream(inputStream), UserExcelModel.class); List<User> userList = new ArrayList<>(); list.forEach(demo->{ User user = new User( demo.getUserName(), demo.getPassword(), demo.getRealName(), demo.getPhone(), demo.getEmail()); userList.add(user); }); System.out.println(list.size()); //將表格數據保存到數據庫 iUserService.saveOrUpdateBatch(userList); } catch (IOException e) { e.printStackTrace(); } } @ApiOperation(value = "導出Excel表格", notes = "導出Excel表格") @RequestMapping(value = "/exprotExcel", method = RequestMethod.POST) public ResponseEntity exprotExcel() { try { List<User> list = iUserService.list(); List<UserExcelModel> dataList = new ArrayList<>(); list.forEach(user->{ UserExcelModel userExcelModel = new UserExcelModel( user.getUserName(), user.getPassword(), user.getRealName(), user.getPhone(), user.getEmail()); dataList.add(userExcelModel); }); System.out.println(dataList.size()); //數據寫入到字節流 ByteArrayOutputStream bos = new ByteArrayOutputStream(); boolean flag = ExcelUtils.writeExcel(bos, UserExcelModel.class, dataList); //下載文件 String fileName = "下載整改建議.xls"; log.info("開始下載導出的Excel文件"); return ExcelUtils.downloadExcel(fileName, bos); } catch (Exception e) { e.printStackTrace(); } return null; } } 

打開swagger,點擊測試,可以看到成功讀取到了Excel文件的數據,並成功插入到數據庫

2、導出測試【下載導出文件】

點擊swagger方法測試或者直接在瀏覽器中輸入https://www.cnblogs.com/xulijun137/,可以看到成下載了導出文件

【說明:在swagger中下載的文件名是亂碼,暫時不知道哪里出了問題,后續知道原因再補充說明】

打開可以看到的確成功從把數據庫數據導出並成功下載了

謝謝讀者支持,下次再見!

===============================================================================

如果您覺得此文有幫助,可以打賞點錢給我支付寶或掃描二維碼


免責聲明!

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



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