springboot2.1.8使用poi導出數據生成excel(.xlsx)文件


前言:在實際開發中經常需要將數據庫的數據導出成excel文件,poi方式則是其中一種較為常用的導出框架。簡單讀取excel文件在之前的一篇有說明

本項目實現需求:user發出一個導出student信息的請求,直接下載包含所有student信息的excel文件到本機。只貼出關鍵代碼,未貼出的很簡單,自行腦補

整體流程(服務器端):接收請求------>取出數據庫數據------>將數據存成excel臨時文件------>通過響應頭讓瀏覽器下載此臨時文件------>刪除臨時文件

項目結構:

 

 

 

1.導入依賴

<!--poi-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.0</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.0</version>
</dependency>

 2.controller

package com.zjk.excel.controller;

import com.zjk.excel.service.UserServiceI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * @Auther: zjk
 * @Date: 2019/9/16
 * @Description:
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserServiceI userServiceI;

    @RequestMapping("/export")
    public void exportStu(HttpServletResponse response){
        //設置默認的下載文件名
        String name = "學生信息表.xlsx";
        try {
            //避免文件名中文亂碼,將UTF8打散重組成ISO-8859-1編碼方式
            name = new String (name.getBytes("UTF8"),"ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //設置響應頭的類型
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        //讓瀏覽器下載文件,name是上述默認文件下載名
        response.addHeader("Content-Disposition","attachment;filename=\"" + name + "\"");
        InputStream inputStream=null;
        OutputStream outputStream=null;
        //在service層中已經將數據存成了excel臨時文件,並返回了臨時文件的路徑
        String downloadPath = userServiceI.exportStu();
        //根據臨時文件的路徑創建File對象,FileInputStream讀取時需要使用
        File file = new File(downloadPath);
        try {
            //通過FileInputStream讀臨時文件,ServletOutputStream將臨時文件寫給瀏覽器
            inputStream = new FileInputStream(file);
            outputStream = response.getOutputStream();
            int len = -1;
            byte[] b = new byte[1024];
            while((len = inputStream.read(b)) != -1){
                outputStream.write(b);
            }
            //刷新
            outputStream.flush();
         } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //關閉輸入輸出流
            try {
                if(inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        //最后才能,刪除臨時文件,如果流在使用臨時文件,file.delete()是刪除不了的
        file.delete();
    }
}

3.service

package com.zjk.excel.service.impl;

import com.zjk.excel.dao.StudentDao;
import com.zjk.excel.dao.UserDao;
import com.zjk.excel.entity.Student;
import com.zjk.excel.service.UserServiceI;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @Auther: zjk
 * @Date: 2019/9/16
 * @Description:
 */
@Service
public class UserService implements UserServiceI {
  //創建臨時文件存放的路徑
    private String temp="d:\\temp\\excel\\";

    @Autowired
    UserDao userDao;

    @Autowired
    StudentDao studentDao;

    @Override
    public String exportStu() {

        List<Student> list = studentDao.queryAllStu();
        //創建工作簿
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
        //創建工作表
        XSSFSheet sheet = xssfWorkbook.createSheet();
        xssfWorkbook.setSheetName(0,"學生信息表");
        //創建表頭
        XSSFRow head = sheet.createRow(0);
        String[] heads = {"編號","姓名","年齡","性別","手機號"};
        for(int i = 0;i < 5;i++){
            XSSFCell cell = head.createCell(i);
            cell.setCellValue(heads[i]);
        }
        for (int i = 1;i <= 4;i++) {
            Student student = list.get(i - 1);
            //創建行,從第二行開始,所以for循環的i從1開始取
            XSSFRow row = sheet.createRow(i);
            //創建單元格,並填充數據
            XSSFCell cell = row.createCell(0);
            cell.setCellValue(student.getS_id());
            cell = row.createCell(1);
            cell.setCellValue(student.getS_name());
            cell = row.createCell(2);
            cell.setCellValue(student.getS_age());
            cell = row.createCell(3);
            cell.setCellValue("男".equals(student.getS_gender().trim())?"男":"女");
            cell = row.createCell(4);
            cell.setCellValue(student.getS_tel());
        }
        //創建臨時文件的目錄
        File file = new File(temp);
        if(!file.exists()){
            file.mkdirs();
        }
        //臨時文件路徑/文件名
        String downloadPath = file + "\\"  +System.currentTimeMillis() + UUID.randomUUID();
        OutputStream outputStream = null;
        try {
       //使用FileOutputStream將內存中的數據寫到本地,生成臨時文件 outputStream
= new FileOutputStream(downloadPath); xssfWorkbook.write(outputStream); outputStream.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { if(outputStream != null) { outputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } return downloadPath; } }

4.效果

WPS打開后:可以說是非常的丑陋了,接下來優化一下

在service中增加如下代碼:總體而言還是很麻煩的,創建CellStyle,還要在你想改變樣式的cell進行cell.setCellStyle(style1)才可以

*博主用的版本比較新,所以很多地方較舊版本有區別

        //創建styleHead
        CellStyle styleHead = xssfWorkbook.createCellStyle();
        styleHead.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());//背景色
        styleHead.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        styleHead.setAlignment(HorizontalAlignment.CENTER);//水平居中
        XSSFFont font = xssfWorkbook.createFont();
        font.setBold(true);//加粗
        font.setFontHeight((short)240);//字體大小
        styleHead.setFont(font);
        //創建style1
        CellStyle style1 = xssfWorkbook.createCellStyle();
        style1.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());//背景色
        style1.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style1.setAlignment(HorizontalAlignment.CENTER);//水平居中
        //創建style2
        CellStyle style2 = xssfWorkbook.createCellStyle();
        style2.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE.getIndex());//背景色
        style2.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style2.setAlignment(HorizontalAlignment.CENTER);//水平居中    
     sheet.setColumnWidth(4,3500);//給第5列設置寬度(tel欄)

優化后:

 

 

 總結一下:

        poi的簡單使用還是不難的,說白了就數據庫一個表對應一個sheet,表的一行對應一個row,表某一行的一個數據對應一個cell,嗯,就是這么簡單。

  說到調樣式就非常頭疼了,而且新版本的較之前改動比較大,百度出來的東西很多都沒法用,勉強搗鼓了一些出來。

  最后給自己打打氣-——世上無難事,只要肯登攀!

 注意事項:

   不要使用post請求,應該用get請求

 最后推薦一個中文poi文檔:

https://www.cnblogs.com/fqfanqi/p/6172223.html

 


免責聲明!

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



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