spring boot 導出數據到excel


手把手教你springboot中導出數據到excel中

問題來源:

前一段時間公司的項目有個導出數據的需求,要求能夠實現全部導出也可以多選批量導出(雖然不是我負責的,我自己研究了研究),我們的項目是xboot前后端分離系統,后端的核心為SpringBoot 2.2.6.RELEASE,因此今天我主要講述后端的操作實現,為了簡化需求,我將需要導出的十幾個字段簡化為5個字段,導出的樣式模板如下:

實現步驟:

打開一個你平時練習使用的springboot的demo,開始按照以下步驟加入代碼進行操作。

1.添加maven依賴

1
2
3
4
5
6
<!--Excel-->
<dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi-ooxml</artifactId>
     <version> 3.11 </version>
</dependency>   

 poi-ooxml是一個excel表格的操作工具包,處理的單頁數據量也是百萬級別的,因此我們選擇的是poi-ooxml.

2.編寫excel工具類

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import  org.apache.poi.ss.usermodel.Cell;
import  org.apache.poi.ss.usermodel.Row;
import  org.apache.poi.ss.usermodel.Sheet;
import  org.apache.poi.xssf.streaming.SXSSFWorkbook;
import  javax.servlet.http.HttpServletResponse;
import  java.io.IOException;
import  java.io.OutputStream;
import  java.io.UnsupportedEncodingException;
import  java.util.List;
 
public  class  ExcelUtil {
     /**
      * 用戶信息導出類
      * @param response 響應
      * @param fileName 文件名
      * @param columnList 每列的標題名
      * @param dataList 導出的數據
      */
     public  static  void  uploadExcelAboutUser(HttpServletResponse response,String fileName,List<String> columnList,<br>List<List<String>> dataList){
         //聲明輸出流
         OutputStream os =  null ;
         //設置響應頭
         setResponseHeader(response,fileName);
         try  {
             //獲取輸出流
             os = response.getOutputStream();
             //內存中保留1000條數據,以免內存溢出,其余寫入硬盤
             SXSSFWorkbook wb =  new  SXSSFWorkbook( 1000 );
             //獲取該工作區的第一個sheet
             Sheet sheet1 = wb.createSheet( "sheet1" );
             int  excelRow =  0 ;
             //創建標題行
             Row titleRow = sheet1.createRow(excelRow++);
             for ( int  i =  0 ;i<columnList.size();i++){
                 //創建該行下的每一列,並寫入標題數據
                 Cell cell = titleRow.createCell(i);
                 cell.setCellValue(columnList.get(i));
             }
             //設置內容行
             if (dataList!= null  && dataList.size()> 0 ){
                 //序號是從1開始的
                 int  count =  1 ;
                 //外層for循環創建行
                 for ( int  i =  0 ;i<dataList.size();i++){
                     Row dataRow = sheet1.createRow(excelRow++);
                     //內層for循環創建每行對應的列,並賦值
                     for ( int  j = - 1 ;j<dataList.get( 0 ).size();j++){ //由於多了一列序號列所以內層循環從-1開始
                         Cell cell = dataRow.createCell(j+ 1 );
                         if (j==- 1 ){ //第一列是序號列,不是在數據庫中讀取的數據,因此手動遞增賦值
                             cell.setCellValue(count++);
                         } else { //其余列是數據列,將數據庫中讀取到的數據依次賦值
                             cell.setCellValue(dataList.get(i).get(j));
                         }
                     }
                 }
             }
             //將整理好的excel數據寫入流中
             wb.write(os);
         catch  (IOException e) {
             e.printStackTrace();
         finally  {
             try  {
                 // 關閉輸出流
                 if  (os !=  null ) {
                     os.close();
                 }
             catch  (IOException e) {
                 e.printStackTrace();
             }
         }
     }
 
     /*
         設置瀏覽器下載響應頭
      */
     private  static  void  setResponseHeader(HttpServletResponse response, String fileName) {
         try  {
             try  {
                 fileName =  new  String(fileName.getBytes(), "ISO8859-1" );
             catch  (UnsupportedEncodingException e) {
                 e.printStackTrace();
             }
             response.setContentType( "application/octet-stream;charset=UTF-8" );
             response.setHeader( "Content-Disposition" "attachment;filename=" + fileName);
             response.addHeader( "Pargam" "no-cache" );
             response.addHeader( "Cache-Control" "no-cache" );
         catch  (Exception ex) {
             ex.printStackTrace();
         }
     }
}

 網上的excel的工具類有很多,但很多並不是你復制過來就能直接使用的,因此需要我們深究其原理,這樣可以應對不同的場景寫出屬於我們自己的合適的代碼,這里就不一一解釋了,代碼中注釋加的很清楚,有不懂的可以留言評論。

3.編寫controller,service,serviceImpl,dao,entity

3.1 entity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import  io.swagger.annotations.ApiModelProperty;
import  lombok.Data;
import  org.hibernate.annotations.Where;
import  javax.persistence.*;
import  java.math.BigDecimal;
 
@Data
@Entity
@Where (clause =  "del_flag = 0" )
@Table (name =  "t_scf_item_data" )
public  class  ItemData{
     private  static  final  long  serialVersionUID = 1L;
 
     @Id
     @TableId
     @ApiModelProperty (value =  "唯一標識" )
     private  String id = String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
 
     @ApiModelProperty (value =  "創建者" )
     @CreatedBy
     private  String createBy;
 
     @CreatedDate
     @JsonFormat (timezone =  "GMT+8" , pattern =  "yyyy-MM-dd HH:mm:ss" )
     @DateTimeFormat (pattern =  "yyyy-MM-dd HH:mm:ss" )
     @ApiModelProperty (value =  "創建時間" )
     private  Date createTime;
    
     @ApiModelProperty (value =  "項目編號" )
     private  String itemNo;
     @ApiModelProperty (value =  "項目名稱" )
     private  String itemName;
     
     @ApiModelProperty (value =  "刪除標志 默認0" )
     private  Integer delFlag =  0 ;   
}

 3.2 dao

1
2
3
4
5
6
7
8
9
10
11
12
import  cn.exrick.xboot.modules.item.entity.ItemData;
import  org.springframework.data.jpa.repository.Query;
import  org.springframework.stereotype.Repository;
import  java.util.List;
 
@Repository
public  interface  ItemDataDao{
   @Query (value =  "select a.item_no,a.item_name,concat(a.create_time),a.create_by from t_scf_item_data a where a.del_flag = 0 limit 5" ,nativeQuery =  true )
     List<List<String>> findAllObject();
     @Query (value =  "select a.item_no,a.item_name,concat(a.create_time),a.create_by  from t_scf_item_data a where a.del_flag = 0 and a.id in ?1 limit 5" ,nativeQuery =  true )
     List<List<String>> findByIds(List<String> idList);
}

 3.3 service

1
2
3
4
5
6
import  javax.servlet.http.HttpServletResponse;
import  java.util.List;
 
public  interface  TestService {
     void  exportExcel(List<String> idList, HttpServletResponse response);
}

 3.4 serviceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import  cn.exrick.xboot.common.utils.ExcelUtil;
import  cn.exrick.xboot.modules.item.dao.ItemDataDao;
import  cn.exrick.xboot.modules.item.service.TestService;
import  org.springframework.beans.factory.annotation.Autowired;
import  org.springframework.stereotype.Service;
import  org.springframework.transaction.annotation.Transactional;
import  javax.servlet.http.HttpServletResponse;
import  java.util.ArrayList;
import  java.util.Arrays;
import  java.util.List;
 
@Transactional
@Service
public  class  TestServiceImpl  implements  TestService {
 
     @Autowired
     private  ItemDataDao itemDataDao;
     @Override
     public  void  exportExcel(List<String> idList, HttpServletResponse response) {
         List<List<String>> dataList =  new  ArrayList<>();
         if (idList ==  null  || idList.size() ==  0 ){
               dataList = itemDataDao.findAllObject();
         } else {
               dataList = itemDataDao.findByIds(idList);
         }
         List<String> titleList = Arrays.asList( "序號" , "項目編碼" "項目名稱" "創建時間" "創建人" );
         ExcelUtil.uploadExcelAboutUser(response, "apply.xlsx" ,titleList,dataList);
     }
}

 3.5 controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import  cn.exrick.xboot.modules.item.service.TestService;
import  io.swagger.annotations.ApiOperation;
import  lombok.extern.slf4j.Slf4j;
import  org.springframework.beans.factory.annotation.Autowired;
import  org.springframework.web.bind.annotation.RequestBody;
import  org.springframework.web.bind.annotation.RequestMapping;
import  org.springframework.web.bind.annotation.RequestMethod;
import  org.springframework.web.bind.annotation.RestController;
 
import  javax.servlet.http.HttpServletResponse;
import  java.util.List;
import  java.util.Map;
@Slf4j
@RestController
@RequestMapping ( "/test" )
public  class  TestController {
 
     @Autowired
     private  TestService testService;
 
     @RequestMapping (value =  "/exportExcel" , method = RequestMethod.POST)
     @ApiOperation (value =  "導出excel" ,produces= "application/octet-stream" )
     public  void  exportCorpLoanDemand( @RequestBody  Map<String,List<String>> map, HttpServletResponse response){ ;
         log.info( "測試:{}" ,map);
         testService.exportExcel(map.get( "list" ),response);
     }
}

 

4.測試

測試的話可以使用swagger或者postman,甚至你前端技術足夠ok的話也可以寫個簡單的頁面進行測試,我是用的是swaager進行的測試,下面就是我測試的結果了:

 

 

 

 

 

原文鏈接:https://www.cnblogs.com/zaevn00001/p/13353744.html?utm_source=tuicool


免責聲明!

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



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