springboot 上傳下載、導入導出


一、上傳下載功能樣例

application.yml配置文件上傳大小限制

#上傳文件設置 springboot上傳文件默認支持的大小為 1mb
spring: 
  servlet:
    multipart:
      #單個數據的大小
      max-file-size: 20MB
      #總數據的大小
      max-request-size: 100MB

上傳下載功能代碼

package com.example.code.bot_monomer.controller.common;

/**
 * @author: shf
 * description: 文件的上傳下載
 * date: 2019/11/9 21:04
 */

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@RequestMapping("/fileUpOrDown")
public class UploadController {

    /**
     * 上傳單個文件
     */
    @PostMapping("/uploadSingle")
    public String uploadSingleFile(@RequestParam("fileUpName") MultipartFile file) {//HttpServletRequest request
        /**
         * 這里提到兩種接收參數的方式:需要注意一點區別 下面的上傳多個文件也是同理
         * 直接用 @RequestParam("fileUpName") MultipartFile file
         *      接收文件參數 如果前端沒有選擇文件 請求后台報錯,Current request is not a multipart request
         *      前端顯示的是500錯誤
         * 替換為  HttpServletRequest request
         *        MultipartFile file = ((MultipartHttpServletRequest)request).getFile("fileUpName"); 獲取文件參數
         *        如果沒有選擇文件 后台報錯 cannot be cast to org.springframework.web.multipart.MultipartHttpServletRequest
         *        不過方便在該行代碼做異常處理等返回設置對應的code msg等統一形式。
         */
        //MultipartFile file = ((MultipartHttpServletRequest)request).getFile("fileUpName");

        if (file.isEmpty()) {
            return "上傳文件不能為空";
        }
        //獲取文件名,帶后綴
        String fileName = file.getOriginalFilename();
        /*如果限制文件上傳類型例如:該接口限制只能上傳圖片,則增加圖片格式校驗*/
        List<String> imageType = Stream.of("jpg","jpeg", "png", "bmp", "gif").collect(Collectors.toList());
        // 獲取文件的后綴格式
        String fileSuffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        if (!imageType.contains(fileSuffix)) return "非法文件";

        //加個UUID拼接,盡量避免文件名稱重復
        String path = "E:" + File.separator + "ces" + File.separator + UUID.randomUUID().toString().replace("-","") + "_" + fileName;
        File dest = new File(path);
        //判斷文件是否已經存在,如果可以直接覆蓋則忽略 或 再重新生成該文件的時間戳文件直到不重復
        if (dest.exists()) return "上傳的文件名已存在";
        //判斷文件父目錄是否存在
        if (!dest.getParentFile().exists())  dest.getParentFile().mkdir();
        //保存文件
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
            return "上傳文件異常";
        }
        return "Success";
    }

    /**
     * 上傳多個文件
     */
    @PostMapping("/uploadMore")
    public String uploadMoreFile(@RequestParam("fileNames") List<MultipartFile> files) {//HttpServletRequest request
        //List<MultipartFile> files = ((MultipartHttpServletRequest)request).getFiles("fileName");
        if (Objects.isNull(files) || files.size() < 1) return "文件不能為空";
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename();
            //加個UUID拼接,盡量避免文件名稱重復
            String path = "E:" + File.separator + "ces" + File.separator + UUID.randomUUID().toString().replace("-","") + "_" + fileName;
            File dest = new File(path);
            //判斷文件是否已經存在,如果可以直接覆蓋則忽略 或 再重新生成該文件的時間戳文件直到不重復
            //if (dest.exists()) return "上傳的文件名已存在";
            //判斷文件父目錄是否存在
            if (!dest.getParentFile().exists())  dest.getParentFile().mkdir();
            //保存文件
            try {
                file.transferTo(dest);
            } catch (IOException e) {
                e.printStackTrace();
                return "上傳文件異常";
            }
        }
        return "Success";
    }

    /**
     * 下載文件
     */
    @RequestMapping("/downLoadFile")
    public String downLoadFile(HttpServletResponse response, @RequestParam("fileName") String filePathName) {
        File file = new File(filePathName);
        if (!file.exists()) return "文件不存在";
        try(
            InputStream inStream = new FileInputStream(filePathName);
            OutputStream os = response.getOutputStream();
            ) {
            response.reset();
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(filePathName,"UTF-8"));
            byte[] buff = new byte[1024];
            int len = -1;
            while ((len = inStream.read(buff)) > 0) {
                os.write(buff, 0, len);
            }
            os.flush();
        } catch (Exception e) {
            e.printStackTrace();
            return "下載文件異常";
        }
        return "Success";
    }

}

二、導入導出Excel

java中比較流行的用poi,但是每次都要寫大段工具類來搞定這事兒,此處推薦一個別人造好的輪子【easypoi】。

1、引入依賴

     <!--easypoi-->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>3.0.3</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>3.0.3</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>3.0.3</version>
        </dependency>                

2、編寫實體類

  • 處注意必須要有空構造函數,否則會報錯“對象創建錯誤”
  • 關於注解@Excel,其他還有@ExcelCollection,@ExcelEntity ,@ExcelIgnore,@ExcelTarget等,此處我們用不到,可以去官方查看更多
屬性 類型 類型 說明

name

String

null

列名

needMerge

boolean

fasle

縱向合並單元格

orderNum

String

"0"

列的排序,支持name_id

replace

String[]

{}

值得替換 導出是{a_id,b_id} 導入反過來

savePath

String

"upload"

導入文件保存路徑

type

int

1

導出類型 1 是文本 2 是圖片,3 是函數,10 是數字 默認是文本

width

double

10

列寬

height

double

10

列高,后期打算統一使用@ExcelTarget的height,這個會被廢棄,注意

isStatistics

boolean

fasle

自動統計數據,在追加一行統計,把所有數據都和輸出這個處理會吞沒異常,請注意這一點

isHyperlink

boolean

false

超鏈接,如果是需要實現接口返回對象

isImportField

boolean

true

校驗字段,看看這個字段是不是導入的Excel中有,如果沒有說明是錯誤的Excel,讀取失敗,支持name_id

exportFormat

String

""

導出的時間格式,以這個是否為空來判斷是否需要格式化日期

importFormat

String

""

導入的時間格式,以這個是否為空來判斷是否需要格式化日期

format

String

""

時間格式,相當於同時設置了exportFormat 和 importFormat

databaseFormat

String

"yyyyMMddHHmmss"

導出時間設置,如果字段是Date類型則不需要設置 數據庫如果是string 類型,這個需要設置這個數據庫格式,用以轉換時間格式輸出

numFormat

String

""

數字格式化,參數是Pattern,使用的對象是DecimalFormat

imageType

int

1

導出類型 1 從file讀取 2 是從數據庫中讀取 默認是文件 同樣導入也是一樣的

suffix

String

""

文字后綴,如% 90 變成90%

isWrap

boolean

true

是否換行 即支持\n

mergeRely

int[]

{}

合並單元格依賴關系,比如第二列合並是基於第一列 則{1}就可以了

mergeVertical

boolean

fasle

縱向合並內容相同的單元格

UserEntity

package com.example.code.bot_monomer.entity;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;

/**
 * @author: shf
 * description:
 * date: 2019/11/9 20:08
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@TableName("user")
public class UserEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Excel(name = "ID", orderNum = "0")
    private Long id;
    @Excel(name = "姓名", orderNum = "1")
    private String userName;
    @Excel(name = "年齡", orderNum = "2")
    private Integer age;
    @Excel(name = "郵箱", orderNum = "3")
    private String email;
    @Excel(name = "出生日期", exportFormat = "yyyy-MM-dd",importFormat="yyyy-MM-dd",orderNum = "4")
    private Date birth;
}

ExcelUtil工具類

package com.example.code.bot_monomer.utils;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * @author: shf
 * description:
 * date: 2019/11/10 18:51
 */
public class ExcelUtil {
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass,String fileName,boolean isCreateHeader, HttpServletResponse response){
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setCreateHeadRows(isCreateHeader);
        defaultExport(list, pojoClass, fileName, response, exportParams);

    }
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass,String fileName, HttpServletResponse response){
        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
    }
    public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response){
        defaultExport(list, fileName, response);
    }

    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams,pojoClass,list);
        if (workbook != null);
        downLoadExcel(fileName, response, workbook);
    }

    private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            //throw new NormalException(e.getMessage());
            e.printStackTrace();
        }
    }
    private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
        if (workbook != null);
        downLoadExcel(fileName, response, workbook);
    }

    public static <T> List<T> importExcel(String filePath,Integer titleRows,Integer headerRows, Class<T> pojoClass){
        if (StringUtils.isBlank(filePath)){
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        }catch (NoSuchElementException e){
            //throw new NormalException("模板不能為空");
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
            //throw new NormalException(e.getMessage());
        }
        return list;
    }
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass){
        if (file == null){
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        }catch (NoSuchElementException e){
           // throw new NormalException("excel文件不能為空");
            e.printStackTrace();
        } catch (Exception e) {
            //throw new NormalException(e.getMessage());
            e.printStackTrace();
        }
        return list;
    }
}

測試Controller

package com.example.code.bot_monomer.controller.common;

import com.example.code.bot_monomer.entity.UserEntity;
import com.example.code.bot_monomer.utils.ExcelUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: shf
 * description:
 * date: 2019/11/10 18:55
 */
@RestController
@RequestMapping("/excel")
public class ExcelController {

    /**
     * Excel導出
     */
    @RequestMapping("exportExcel")
    public void exportExcel(HttpServletResponse response) throws IOException {

        UserEntity user1 = UserEntity.builder().id(1L).userName("張三").age(10).birth(new Date()).build();
        UserEntity user2 = UserEntity.builder().id(2L).userName("小李").age(16).birth(new Date()).build();
        UserEntity user3 = UserEntity.builder().id(3L).userName("小王").age(14).birth(new Date()).build();
        List<UserEntity> userList = Stream.of(user1, user2, user3).collect(Collectors.toList());
      
        //導出操作
        ExcelUtil.exportExcel(userList, null, "用戶", UserEntity.class, "測試用戶導出.xlsx", response);

    }

    /**
     * Excel導入
     */
    @PostMapping("importExcel")
    public String importExcel(HttpServletResponse response, @RequestParam("file") MultipartFile file) {
        //解析excel
        List<UserEntity> userList = ExcelUtil.importExcel(file, 0, 1, UserEntity.class);
        //也可以使用String filePath = "xxx.xls";importExcel(String filePath,Integer titleRows,Integer headerRows, Class<T> pojoClass)導入
        System.out.println("導入數據一共【" + userList.size() + "】行");
        System.out.println("導入的數據:" + userList);
        //TODO 保存數據庫

        return "Success";
    }
}

異常處理:

try {
            EasyExcelUtil.exportExcel(exporDatatList, null, "用戶列表", ActiveFissionUserDto.class, "用戶列表.xlsx", response);
        } catch (Exception e) {
            log.error(">>>用戶導出Excel異常:", e);
            exportUserExcelError(response);
        }

//--------------------------------------------
private void exportUserExcelError(HttpServletResponse response) throws IOException {
        response.setHeader("content-type", "text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.print("導出異常");
        writer.flush();
        writer.close();
    }

 

 

參考文章:

https://www.cnblogs.com/shihaiming/p/9415102.html

http://easypoi.mydoc.io/#category_41961

 


免責聲明!

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



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