SpringBoot文件上传与POI的使用

1.使用springboot上传文件

本文所要源码在一个项目中,源码:https://github.com/zhongyushi-git/springboot-upload-download.git。下面的介绍与源码可能有差别,以源码为准!

1.1环境准备

1)新建一个springboot的项目

2)导入web坐标

 <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
</dependency>

1.2实战演练

1)创建文件的工具类,在类中添加一个上传的方法

/**
 * @author zhongyushi
 * @date 2020/9/29 0029
 * @dec 文件工具类,用于上传和下载
 */
public class FileUtil {
    //文件保存的路径
    private static final String STORE_PATH = "D://files";

    public static String uploadFile(MultipartFile file) {
        //设置日期的格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        //设置文件的保存路径是项目运行目录下的uploadFile目录下
        String realPath = new File(STORE_PATH).getAbsolutePath();
        //通过日期 对文件归类,如2019/11/30,2019/11/29
        String format = File.separator + sdf.format(new Date());
        format = format.replace("/", "\\");
        //根据规则创建目录
        File folder = new File(realPath + format);
        if (!folder.isDirectory()) {
            folder.mkdirs();
        }
        //获取文件的原始名
        String oldName = file.getOriginalFilename();
        //获取文件的后缀名
        String suffix = oldName.substring(oldName.lastIndexOf("."));
        //使用uuid设置新的文件名,防止文件名重复
        String newName = UUID.randomUUID().toString() + suffix;
        try {
            //文件保存
            file.transferTo(new File(folder, newName));
            //生成文件的保存路径
            String accessPath = realPath + format + File.separator + newName;
            return accessPath;
        } catch (IOException e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }
}

2)创建文件上传的接口upload

package com.zys.springbootuploaddownload;

import com.zys.springbootuploaddownload.util.FileUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author zhongyushi
 * @date 2020/9/29 0029
 * @dec 上传下载的接口
 */
@RestController
public class TestController {


    /**
     * 文件上传,返回文件保存路径
     * @param file
     * @return
     */
    @PostMapping("/upload")
    public String uploadFile(MultipartFile file){
        String path = FileUtil.uploadFile(file);
        return path;
    }
}

3)在资源目录的static目录下创建一个文件上传的页面upload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
    <form action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file" value="选择文件">
        <input type="submit" value="上传">
    </form>
</body>
</html>

注意:按照上面的写法,页面中type是file的name值必须和后台得参数值相同,否则会出现空指针异常。

4)测试

启动项目,在浏览器输入http://localhost:8080/upload.html,选择文件上传,上传成功时会返回文件保存的位置,此时在指定的目录下会生成多级的目录,最后一级是文件。

2.通过浏览器下载文件

1)在文件的工具类添加两个方法

   /**
     * 指定路径下载文件
     * @param path 文件路径
     * @param filename 文件名,带后缀
     * @param response
     * @throws IOException
     */
    public static void downloadFile(String path, String filename, HttpServletResponse response) throws IOException {
        File file = new File(path + File.separator + filename);
        if (!file.exists()) {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("error");
            return;
        }
        FileInputStream in = new FileInputStream(file);
        downloadFile(filename, in, response);
    }

    /**
     * 通过流下载文件
     *
     * @param filename 文件名,带后缀
     * @param in 输入流
     * @param response
     * @throws IOException
     */
    public static void downloadFile(String filename, InputStream in, HttpServletResponse response) throws IOException {
        //设置浏览器直接下载文件,不打开,并设置文件名的编码
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        int len = 0;
        byte bytes[] = new byte[1024];
        OutputStream out = response.getOutputStream();
        while ((len = in.read(bytes)) > 0) {
            out.write(bytes, 0, len);
        }
        in.close();
    }

2)添加读取资源目录的工具类

package com.zys.springbootuploaddownload.util;

import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

/**
 * @author zhongyushi
 * @date 2020/9/29 0029
 * @dec 根据路径获取文件流
 */
@Component
public class GetFileStream {

    /**
     * 获取资源目录下的文件流
     *
     * @param path 文件路径
     * @param fileName 文件名,带后缀
     * @return
     */
    public InputStream getResourceStream(String path, String fileName) throws FileNotFoundException {
        InputStream stream = this.getClass().getClassLoader().getResourceAsStream(path + File.separator + fileName);
        if (stream == null) {
            throw new FileNotFoundException("路径错误,未找到指定文件");
        }
        return stream;
    }


}

3)在上传的接口添加下载的方法。需要使用@Autowired注入GetFileStream

  /**
     * 从本地下载文件
     * @param response
     * @throws IOException
     */
    @GetMapping("/download1")
    public void download1(HttpServletResponse response) throws IOException {
        String path = "D:\\files";
        String fileName="123.txt";
        FileUtil.downloadFile(path,fileName,response);
    }


    /**
     * 从资源目录下载文件
     * @param response
     * @throws IOException
     */
    @GetMapping("/download2")
    public void download2(HttpServletResponse response) throws IOException {
        String path = "templates";
        String fileName="a.txt";
        InputStream stream = getFileStream.getResourceStream(path, fileName);
        FileUtil.downloadFile(fileName,stream,response);
    }

这里有两个方法,一个是直接下载指定路径下的文件,另一个是下载服务器上资源目录下的文件。

3)在static目录下新建文件下载页面file.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<a href="/download1">下载本地文件</a>
<a href="/download2">下载服务器文件</a>
</body>
</html>

4)测试

启动项目,在浏览器输入http://localhost:8080/file.html,点击下载即可下载文件。下载之前,代码中指定的文件需要存在对应的位置,否则会下载失败,文件的路径可自定义。

3.poi实现文件导入

3.1环境准备

1)导入poi的依赖

     <!-- POI,excel解析相关 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>

2)导入mysql等相关的依赖,配置数据库信息(详见源码)

3)在数据库执行sql脚本。脚本在项目根目录下。

4)导入必需的工具类

package com.zys.springbootuploaddownload.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 读取.properties配置文件的内容至Map中
 */
public class PropertiesUtil {

    /**
     * 读取.properties配置文件的内容至Map
     *
     * @param propertiesFile
     * @return
     * @throws IOException
     */
    public static Map read(String propertiesFile) throws Exception {
        try {
            if (!(propertiesFile.indexOf("properties") > 0)) {
                propertiesFile = propertiesFile + ".properties";
            }
            InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(propertiesFile);
            Properties p = new Properties();
            p.load(inStream);

            Map<Object, Object> map = properties2map(p);
            return map;
        } catch (IOException e) {
            throw new Exception(e);
        }
    }

    /**
     * 将属性文件转为map
     *
     * @param prop
     * @return
     */
    public static Map properties2map(Properties prop) {
        Map<Object, Object> map = new HashMap<Object, Object>();
        Enumeration enu = prop.keys();
        while (enu.hasMoreElements()) {
            Object obj = enu.nextElement();
            Object objv = prop.get(obj);
            map.put(obj, objv);
        }
        return map;
    }

    public static Map<String,String> getKeyAndValue(String fileName,String configName) throws Exception {
        Map<String,String> keyMap=new HashMap<>();
        Map<String, String> map = PropertiesUtil.read("importConfig.properties");
        //过滤文件内容,只截取student的配置
        for (String key : map.keySet()) {
            if (key.startsWith("student.")) {
                String[] split = key.split("student.");
                keyMap.put(map.get(key), split[1]);
            }
        }
        return keyMap;
    }
}

此工具类用来读取指定的配置文件的内容。

package com.zys.springbootuploaddownload.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zys.springbootuploaddownload.entity.ExcelData;
import com.zys.springbootuploaddownload.entity.Student;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: yushizhong
 * @Date: 2020/2/22 12:07
 * @Title: 解析excel内容+导出excel
 * 解析excel:调用readExcel方法
 * 导出excel:浏览器下载调用exportExcel方法
 * 本地下载调用generateExcel方法
 */
public class ExcelUtil {

    public final static String XLSX = ".xlsx";
    public final static String XLS = ".xls";


    /**
     * 获取Excel文件(.xls和.xlsx都支持)
     *
     * @param path 文件全路径
     * @return 解析excle后的Json数据
     */
    public static JSONArray readExcel(String path, Map<String, String> myMap) throws Exception {
        File file = new File(path);
        int res = checkFile(file);
        if (res == 0) {
            System.out.println("File not found");
        } else if (res == 1) {
            return readXLSX(file, myMap);
        } else if (res == 2) {
            return readXLS(file, myMap);
        }
        JSONArray array = new JSONArray();
        return array;
    }

    /**
     * 判断File文件的类型
     *
     * @param file 传入的文件
     * @return 0-文件为空,1-XLSX文件,2-XLS文件,3-其他文件
     */
    public static int checkFile(File file) {
        if (file == null) {
            return 0;
        }
        String fileName = file.getName();
        if (fileName.endsWith(XLSX)) {
            return 1;
        }
        if (fileName.endsWith(XLS)) {
            return 2;
        }
        return 3;
    }

    /**
     * 读取XLSX文件
     *
     * @param file
     * @return
     * @throws IOException
     * @throws InvalidFormatException
     */
    public static JSONArray readXLSX(File file, Map<String, String> myMap) throws IOException, InvalidFormatException {
        Workbook book = new XSSFWorkbook(file);
        //只读第一个sheet表内容
        Sheet sheet = book.getSheetAt(0);
        return read(sheet, book, myMap);
    }

    /**
     * 读取XLS文件
     *
     * @param file 文件对象
     * @throws IOException
     * @throws FileNotFoundException
     */
    public static JSONArray readXLS(File file, Map<String, String> myMap) throws FileNotFoundException, IOException {
        POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream(file));
        Workbook book = new HSSFWorkbook(poifsFileSystem);
        //只读第一个sheet表内容
        Sheet sheet = book.getSheetAt(0);
        return read(sheet, book, myMap);
    }

    /**
     * 解析数据
     *
     * @param sheet 表格sheet对象
     * @param book  用于流关闭
     * @param myMap excel列名替换的值
     * @return
     * @throws IOException
     */
    public static JSONArray read(Sheet sheet, Workbook book, Map<String, String> myMap) throws IOException {
        int rowStart = sheet.getFirstRowNum();    // 首行下标
        int rowEnd = sheet.getLastRowNum();    // 尾行下标
        // 如果首行与尾行相同,表明只有一行,直接返回空数组
        if (rowStart == rowEnd) {
            book.close();
            return new JSONArray();
        }
        // 获取第一行JSON对象键
        Row firstRow = sheet.getRow(rowStart);
        int cellStart = firstRow.getFirstCellNum();
        int cellEnd = firstRow.getLastCellNum();
        Map<Integer, String> keyMap = new HashMap<Integer, String>();
        for (int j = cellStart; j < cellEnd; j++) {
            keyMap.put(j, getValue(firstRow.getCell(j), rowStart, j, book, true));
        }
        keyMap = replaceKey(keyMap, myMap);
        // 获取每行JSON对象的值
        JSONArray array = new JSONArray();
        for (int i = rowStart + 1; i <= rowEnd; i++) {
            Row eachRow = sheet.getRow(i);
            JSONObject obj = new JSONObject();
            StringBuffer sb = new StringBuffer();
            for (int k = cellStart; k < cellEnd; k++) {
                if (eachRow != null) {
                    String val = getValue(eachRow.getCell(k), i, k, book, false);
                    sb.append(val);        // 所有数据添加到里面,用于判断该行是否为空
                    obj.put(keyMap.get(k), val);
                }
            }
            if (sb.toString().length() > 0) {
                array.add(obj);
            }
        }
        book.close();
        return array;
    }

    /**
     * 获取每个单元格的数据
     *
     * @param cell   单元格对象
     * @param rowNum 第几行
     * @param index  该行第几个
     * @param book   主要用于关闭流
     * @param isKey  是否为键:true-是,false-不是。 如果解析Json键,值为空时报错;如果不是Json键,值为空不报错
     * @return
     * @throws IOException
     */
    public static String getValue(Cell cell, int rowNum, int index, Workbook book, boolean isKey) throws IOException {
        // 空白或空
        if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) {
            if (isKey) {
                book.close();
                throw new NullPointerException(String.format("the key on row %s index %s is null ", ++rowNum, ++index));
            } else {
                return "";
            }
        }
        // 0. 数字 类型
        if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            if (HSSFDateUtil.isCellDateFormatted(cell)) {
                Date date = cell.getDateCellValue();
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return df.format(date);
            }
            //防止当作数字而导致最后的0丢失
            DecimalFormat df = new DecimalFormat("0");
            String val = df.format(cell.getNumericCellValue());
            val = val.toUpperCase();
            if (val.contains("E")) {
                val = val.split("E")[0].replace(".", "");
            }
            return val;
        }
        // 1. String类型
        if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
            String val = cell.getStringCellValue();
            if (val == null || val.trim().length() == 0) {
                if (book != null) {
                    book.close();
                }
                return "";
            }
            return val.trim();
        }
        // 2. 公式 CELL_TYPE_FORMULA
        if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
            return cell.getStringCellValue();
        }
        // 4. 布尔值 CELL_TYPE_BOOLEAN
        if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
            return cell.getBooleanCellValue() + "";
        }
        // 5.    错误 CELL_TYPE_ERROR
        return "";
    }

    /**
     * 替换读取的数据key
     *
     * @param oldMap 原始map
     * @param myMap  要替换的value map
     * @return
     */
    public static Map<Integer, String> replaceKey(Map<Integer, String> oldMap, Map<String, String> myMap) {
        Map<Integer, String> newMap = new HashMap<>();
        int size = myMap.size();
        if (oldMap.size() != size) {
            throw new NullPointerException("表格内容无法识别,请检查内容的规范性!");
        } else {
            for (Integer key : oldMap.keySet()) {
                for (String key2 : myMap.keySet()) {
                    if (oldMap.get(key).equals(key2)) {
                        newMap.put(key, myMap.get(key2));
                    }
                }
            }
        }
        return newMap;
    }

    public static void exportExcel(String sheetName, Map<String, String> keyMap, String fileName, List<Map> list, HttpServletResponse response) throws Exception {

    }


    /**
     * 使用浏览器选下载
     *
     * @param response
     * @param fileName 下载时的文件名
     * @param data
     * @throws Exception
     */
    public static void exportExcel(HttpServletResponse response, String fileName, ExcelData data) throws Exception {
        // 告诉浏览器用什么软件可以打开此文件
        response.setHeader("content-Type", "application/vnd.ms-excel");
        // 下载文件的默认名称
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xls", "utf-8"));
        exportExcel(data, response.getOutputStream());
    }

    /**
     * 本地下载
     *
     * @param excelData
     * @param path      文件要存储的路径
     * @return
     * @throws Exception
     */
    public static int generateExcel(ExcelData excelData, String path) throws Exception {
        File f = new File(path);
        FileOutputStream out = new FileOutputStream(f);
        return exportExcel(excelData, out);
    }

    /**
     * 创建excel表
     *
     * @param data
     * @param out
     * @return
     * @throws Exception
     */
    private static int exportExcel(ExcelData data, OutputStream out) throws Exception {
        XSSFWorkbook wb = new XSSFWorkbook();
        int rowIndex = 0;
        try {
            //设置工作表的名字
            String sheetName = data.getName();
            if (null == sheetName) {
                sheetName = "Sheet1";
            }
            //创建工作表
            XSSFSheet sheet = wb.createSheet(sheetName);
            rowIndex = writeExcel(wb, sheet, data);
            wb.write(out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //此处需要关闭 wb 变量
            out.close();
        }
        return rowIndex;
    }


    /**
     * 设置表显示字段
     *
     * @param wb
     * @param sheet
     * @param data
     * @return
     */
    private static int writeExcel(XSSFWorkbook wb, Sheet sheet, ExcelData data) {
        int rowIndex = 0;
        rowIndex = writeTitlesToExcel(wb, sheet, data.getTitles());
        rowIndex = writeRowsToExcel(wb, sheet, data.getRows(), rowIndex);
        autoSizeColumns(sheet, data.getTitles().size() + 1);
        return rowIndex;
    }

    /**
     * 设置表头
     *
     * @param wb
     * @param sheet
     * @param titles
     * @return
     */
    private static int writeTitlesToExcel(XSSFWorkbook wb, Sheet sheet, List<String> titles) {
        int rowIndex = 0;
        int colIndex = 0;
        Font titleFont = wb.createFont();
        //设置字体
        titleFont.setFontName("宋体");
        //设置字号
        titleFont.setFontHeightInPoints((short) 12);
        //设置颜色
        titleFont.setColor(IndexedColors.BLACK.index);
        XSSFCellStyle titleStyle = wb.createCellStyle();
        titleStyle.setFont(titleFont);
        setBorder(titleStyle, BorderStyle.THIN);
        Row titleRow = sheet.createRow(rowIndex);
        titleRow.setHeightInPoints(25);
        colIndex = 0;
        for (String field : titles) {
            Cell cell = titleRow.createCell(colIndex);
            cell.setCellValue(field);
            cell.setCellStyle(titleStyle);
            colIndex++;
        }
        rowIndex++;
        return rowIndex;
    }

    /**
     * 设置内容
     *
     * @param wb
     * @param sheet
     * @param rows
     * @param rowIndex
     * @return
     */
    private static int writeRowsToExcel(XSSFWorkbook wb, Sheet sheet, List<List<Object>> rows, int rowIndex) {
        int colIndex;
        Font dataFont = wb.createFont();
        dataFont.setFontName("宋体");
        dataFont.setFontHeightInPoints((short) 12);
        dataFont.setColor(IndexedColors.BLACK.index);
        XSSFCellStyle dataStyle = wb.createCellStyle();
        dataStyle.setFont(dataFont);
        setBorder(dataStyle, BorderStyle.THIN);
        for (List<Object> rowData : rows) {
            Row dataRow = sheet.createRow(rowIndex);
            dataRow.setHeightInPoints(25);
            colIndex = 0;
            for (Object cellData : rowData) {
                Cell cell = dataRow.createCell(colIndex);
                if (cellData != null) {
                    cell.setCellValue(cellData.toString());
                } else {
                    cell.setCellValue("");
                }
                cell.setCellStyle(dataStyle);
                colIndex++;
            }
            rowIndex++;
        }
        return rowIndex;
    }

    /**
     * 自动调整列宽
     *
     * @param sheet
     * @param columnNumber
     */
    private static void autoSizeColumns(Sheet sheet, int columnNumber) {
        for (int i = 0; i < columnNumber; i++) {
            int orgWidth = sheet.getColumnWidth(i);
            sheet.autoSizeColumn(i, true);
            int newWidth = (int) (sheet.getColumnWidth(i) + 100);
            if (newWidth > orgWidth) {
                sheet.setColumnWidth(i, newWidth);
            } else {
                sheet.setColumnWidth(i, orgWidth);
            }
        }
    }

    /**
     * 设置边框
     *
     * @param style
     * @param border
     */
    private static void setBorder(XSSFCellStyle style, BorderStyle border) {
        style.setBorderTop(border);
        style.setBorderLeft(border);
        style.setBorderRight(border);
        style.setBorderBottom(border);
    }


}

此工具类是用来解析excel内容以及导出excel。

3.2实战演练

1)编写导入接口

    @PostMapping("/import")
    public JSONObject importExcel(MultipartFile file) {
        JSONObject jsonObject = new JSONObject();
        try {
            //获取配置文件的内容
            Map<String, String> keyMap = PropertiesUtil.getKeyAndValue(importConfigName, "student.");
            //上传文件
            String path = FileUtil.uploadFile(file, uploadPath);
            //读取上传的文件内容
            JSONArray jsonArray = ExcelUtil.readExcel(path, keyMap);
            int count = studentService.importExcel(jsonArray);
            if (count >= 0) {
                jsonObject.put("status", true);
                jsonObject.put("msg", "学生信息导入成功");
            } else {
                jsonObject.put("status", false);
                jsonObject.put("msg", "学生信息导入失败");
            }
        } catch (Exception e) {
            log.info("=====学生信息导入发生异常=====" + e.getMessage());
            jsonObject.put("status", false);
            jsonObject.put("msg", "学生信息导入失败");
        }
        return jsonObject;
    }

2)编写导入的实体类、service及dao(见源码)。

3)把资源目录下templates目录下的excel文件复制一份,加入相关的数据

4)在资源目录新建导入的配置文件importConfig.properties,内容如下

#文件的读取和导入相关基础配置

#student相关配置,名字必须叫student,下面同
student.name=姓名
student.sno=学号
student.sex=性别
student.phone=手机号

5)添加导入的页面import.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>导入导出excel</title>
</head>
<body>
    <div>
        <a href="/download2">下载模板</a>
    </div>
    <form action="/import" method="post" enctype="multipart/form-data">
        <input type="file" name="file" value="选择文件">
        <input type="submit" value="导入">
    </form>

</body>
</html>

6)测试。访问http://localhost:8080/import.html,点击导入,选择编辑好的excel,然后导入,会返回导入成功的信息,查看数据库,数据已被导入进来了。

4.poi实现文件导出

1)添加导出的接口

    @GetMapping("/export")
    public void exportExcel(HttpServletResponse response) throws Exception {
        List<Student> list = studentService.queryList();

        ExcelData data = new ExcelData();
        String fileName = "学生信息表";
        //设置工作表名称
        data.setName(fileName);
        //设置表头
        List<String> titles = new ArrayList();
        titles.add("姓名");
        titles.add("学号");
        titles.add("性别");
        titles.add("手机号");
        data.setTitles(titles);
        //设置数据内容
        List<List<Object>> rows = new ArrayList();
        for (Student stu : list) {
            List<Object> row = new ArrayList();
            row.add(stu.getName());
            row.add(stu.getSno());
            row.add(stu.getSex());
            row.add(stu.getPhone());
            rows.add(row);
        }
        data.setRows(rows);
        try {
            String formatName = new SimpleDateFormat("HHmmss").format(new Date());
            ExcelUtil.exportExcel(response, fileName + formatName, data);
        } catch (Exception e) {
            log.info("=====学生信息导出发生异常=====" + e.getMessage());
        }
    }

2)在import页面添加导出的链接

<a href="/export">导出</a>

3)测试。访问http://localhost:8080/import.html,点击导出,即可导出相应的数据。

就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
原文地址:https://www.cnblogs.com/zys2019/p/12245606.html