Springboot導出Excel並下載


一、引入相關依賴

<!--數據導出excel-->
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.17</version>
</dependency>

二、Controller接口

package com.huang.controller;

import com.huang.mapper.UsersMapper;
import com.huang.util.excelExport.ExcelExport2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author:huang
 * @Date:2019-09-21 13:13
 * @Description:<描述>
 */
@Controller
public class TestController {

    @Resource
    private UsersMapper usersMapper;

    @RequestMapping("/test")
    public void testExprotExcel(HttpServletResponse response){

        //創建一個數組用於設置表頭
        String[] arr = new String[]{"ID","用戶名","賬號","密碼","備注"};

        //調用Excel導出工具類
        ExcelExport2.export(response,usersMapper.selectAll(),arr);

    }

}

三、工具類

3.1文件導出excel工具類

大體思路是傳入一個需要導出的數據集合,獲取該對象類,然后遍歷集合,使用下面的類操作工具類,通過反射獲取對象類的屬性的get方法,然后將數據對象的值取出來放到excel里

package com.huang.util.excelExport;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @Author:haung
 * @Date:2019-09-21 11:21
 * @Description:Excel導出工具類,依賴於ClassUtil工具類
 */
public final class ExcelExport2 {

    /**
     * 將傳入的數據導出excel表並下載
     * @param response 返回的HttpServletResponse
     * @param importlist 要導出的對象的集合
     * @param attributeNames 含有每個對象屬性在excel表中對應的標題字符串的數組(請按對象中屬性排序調整字符串在數組中的位置)
     */
    public static void export(HttpServletResponse response, List<?> importlist, String[] attributeNames) {
        //獲取數據集
        List<?> datalist = importlist;

        //聲明一個工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        //生成一個表格
        HSSFSheet sheet = workbook.createSheet();
        //設置表格默認列寬度為15個字節
        sheet.setDefaultColumnWidth((short) 18);

        //獲取字段名數組
        String[] tableAttributeName = attributeNames;
        //獲取對象屬性
        Field[] fields = ClassUtil.getClassAttribute(importlist.get(0));
        //獲取對象get方法
        List<Method> methodList = ClassUtil.getMethodGet(importlist.get(0));

        //循環字段名數組,創建標題行
        Row row = sheet.createRow(0);
        for (int j = 0; j< tableAttributeName.length; j++){
            //創建列
            Cell cell = row.createCell(j);
            //設置單元類型為String
            cell.setCellType(CellType.STRING);
            cell.setCellValue(transCellType(tableAttributeName[j]));
        }
        //創建普通行
        for (int i = 0;i<datalist.size();i++){
            //因為第一行已經用於創建標題行,故從第二行開始創建
            row = sheet.createRow(i+1);
            //如果是第一行就讓其為標題行
            Object targetObj = datalist.get(i);
            for (int j = 0;j<fields.length;j++){
                //創建列
                Cell cell = row.createCell(j);
                cell.setCellType(CellType.STRING);
                //
                try {
                    Object value = methodList.get(j).invoke(targetObj, new Object[]{});
                    cell.setCellValue(transCellType(value));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        response.setContentType("application/octet-stream");
        //默認Excel名稱
        response.setHeader("Content-Disposition", "attachment;fileName="+"test.xls");

        try {
            response.flushBuffer();
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static String transCellType(Object value){
        String str = null;
        if (value instanceof Date){
            Date date = (Date) value;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            str = sdf.format(date);
        }else{
            str = String.valueOf(value);
            if (str == "null"){
                str = "";
            }
        }

        return str;
    }

}

3.2類操作工具類

該工具類用於Excel導出工具類里的屬性操作

package com.huang.util.excelExport;

import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author:huang
 * @Date:2019-09-21 13:41
 * @Description:關於類的操作的工具類
 */
public final class ClassUtil {

    private ClassUtil() {
        throw new Error("工具類不允許實例化!");
    }

    /**
     * 獲取類屬性
     * @param targetObj 要獲取屬性的類
     * @return 含有類屬性的集合
     */
    public static Field[] getClassAttribute(Object targetObj){

        Class<?> objectClass = targetObj.getClass();
        return objectClass.getDeclaredFields();

    }

    /**
     * 獲取對象的所有get或set方法
     * @param targetObj 要獲取屬性的類
     * @param methodKeyword get或者set關鍵字
     * @return 含有類get或set方法的集合
     */
    public static List<Method> getMethod(Object targetObj,String methodKeyword){
        List<Method> methodList = new ArrayList<>();

        Class<?> objectClass = targetObj.getClass();

        Field[] field = objectClass.getDeclaredFields();
        for (int i = 0;i<field.length;i++){
            //獲取屬性名並組裝方法名
            String fieldName = field[i].getName();
            String getMethodName = methodKeyword
                + fieldName.substring(0, 1).toUpperCase()
                + fieldName.substring(1);

            try {
                Method method = objectClass.getMethod(getMethodName,new Class[]{});
                methodList.add(method);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return methodList;
    }

    /**
     * 獲取對象的所有get方法
     * @param targetObj 要獲取屬性的類
     * @return 含有類方法的集合
     */
    public static List<Method> getMethodGet(Object targetObj){
        return getMethod(targetObj,"get");
    }

    /**
     * 獲取對象的所有set方法
     * @param targetObj 要獲取屬性的類
     * @return 含有類方法的集合
     */
    public static List<Method> getMethodSet(Object targetObj){
        return getMethod(targetObj,"set");
    }
}

四、后續補充的話

這篇文章是做項目的時候第一次遇到導出Excel需求的時候寫的,當時頭鐵硬生生自己造了個輪子出來,上述代碼可以用,但是仍然存在表頭設置麻煩,內存占用高,而且導出數據可控性低的問題。
實際上,針對這個需求:如果是需要導出大量數據而沒有排版要求的話,可以用EasyExcel,順帶還能把Excel導入給解決了;如果是需要按照復雜模板導出的話,可以使用jxls,或者大佬進一步封裝的jxlss。
這些都是實用而且成熟的框架,如果是有確實的業務用途而不是參考學習的話,建議直接使用這些框架......


免責聲明!

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



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