【贫民版】Springboot导入返回错误Excel表格 ---- 通过session存储字节数据,再获取写到响应体中。

news2024/12/24 2:11:08

目录

  • 前言
  • 一、需求
  • 二、需求分析
  • 三、代码


前言

在开发中会遇到导入文件后,失败的数据需要整理在加上导入失败原因。

按照目前主流的方法,要么通过流输出到response响应体中,或者把失败的excel上传到服务器中,返回url让前端下载。


一、需求

导入文件后,把未满足条件的记录和未满足的原因导出,让业务人员修改后二次导入。

二、需求分析

1、当前端请求到后端时,可以直接通过response直接导出文件,但是会有其他情况,前端需要返回码去判断展示不同的页面。

2、故放弃第1种方法,需要让 excel 暂存在一个地方 , 通过返回的数据, 由前端判断去获取excel。

3、有多种实现方法。 本文主要介绍的是在 session中存储。

三、代码

相关依赖

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

<dependency>
   <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>

controller

package com.example.springboot_demo.testImpl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
public class TestController {

    @GetMapping("/import")
    public String test2(@RequestParam(value = "file", required = false) MultipartFile file, HttpServletRequest request){
        // TODO 处理file

        // 构造错误数据
        List<TempFileUtil.ErrorExportVO> errorExportVOList = new ArrayList<>();
        TempFileUtil.ErrorExportVO exportVO1 = new TempFileUtil.ErrorExportVO();
        exportVO1.setFileName("我是错误的文件名!");
        exportVO1.setErrorMsg("文件名错误!");
        TempFileUtil.ErrorExportVO exportVO2 = new TempFileUtil.ErrorExportVO();
        exportVO2.setFileName("我是错误的文件名2!");
        exportVO2.setErrorMsg("文件名错误2!");
        errorExportVOList.add(exportVO1);
        errorExportVOList.add(exportVO2);

        String uuid;
        try{
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ExcelWriterBuilder write = EasyExcel.write(outputStream, TempFileUtil.ErrorExportVO.class);
            write.sheet("sheet1").doWrite(errorExportVOList);
            uuid = TempFileUtil.addExcel(request, outputStream, "错误信息");
            outputStream.close();
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
        return uuid;
    }


    //下载临时文件
    @GetMapping("/downloadTempFile")
    public void downloadTempFile(@RequestParam("tempFileId") String tempFileId,
                                 HttpServletRequest request, HttpServletResponse response) {
        final TempFileUtil.TempFileBean fileBean = TempFileUtil.get(request, tempFileId);
        if (fileBean == null) {
            throw new RuntimeException("对象不存在!");
        }
        TempFileUtil.exportBinary(fileBean, response);
        TempFileUtil.remove(request, tempFileId);
    }
}

工具类。 为了方便阅读,把实体类放到里面了。

package com.example.springboot_demo.testImpl;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
public class TempFileUtil {
    @SuppressWarnings("unchecked")
    private static Map<String, TempFileBean> getFileMap(HttpServletRequest request) {
        if (request == null) {
            return new HashMap<>();
        }
        final HttpSession session = request.getSession();
        if (session.getAttribute("fileMap") == null) {
            session.setAttribute("fileMap", new HashMap<String, TempFileBean>());
        }
        return (Map<String, TempFileBean>) session.getAttribute("fileMap");
    }

    public static void put(HttpServletRequest request, final TempFileBean fileBean) {
        getFileMap(request).put(fileBean.getFileId(), fileBean);
    }

    public static TempFileBean get(HttpServletRequest request, final String fileId) {
        return getFileMap(request).get(fileId);
    }

    public static void remove(HttpServletRequest request, final String fileId) {
        getFileMap(request).remove(fileId);
    }

    public static String addExcel(HttpServletRequest request, ByteArrayOutputStream outputStream, String fileName) {
        byte[] excelData = outputStream.toByteArray();
        TempFileBean fileBean = new TempFileBean();
        String fileId = UUID.randomUUID().toString();
        fileBean.setFileId(fileId);
        fileBean.setFileName(fileName);
        fileBean.setFileContent(excelData);
        TempFileUtil.put(request, fileBean);
        return fileId;

    }

    public static void exportBinary(TempFileBean fileBean, HttpServletResponse response) {
        try {
            // 对中文文件名进行 URL 编码
            String encodedFileName = URLEncoder.encode(fileBean.getFileName(), "utf-8") + ExcelTypeEnum.XLSX.getValue();
            response.setContentType("multipart/form-data");
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);

            try (OutputStream os = response.getOutputStream()) {
                os.write(fileBean.getFileContent());
                os.flush();
            } catch (Exception e) {
                log.info("系统异常");
            }
        } catch (Exception e) {
            log.info("系统异常");
        }


    }

    @Data
    public static class TempFileBean {
        private String fileId;
        private String fileName;
        private byte[] fileContent;
    }

    @Data
    public static class ErrorExportVO {
        @ExcelProperty(value = "文件名")
        @ColumnWidth(30)
        private String fileName;
        @ExcelProperty(value = "错误原因")
        @ColumnWidth(30)
        private String errorMsg;
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1551170.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pyqt 创建右键菜单栏

class MainModule(QMainWindow, Ui_MainWindow):def __init__(self):super().__init__(parentNone)self.setupUi(self)# 允许出现菜单栏self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)# 对空间添加右键菜单栏处理 self.tableWidget.customContextMenuRequested.…

Redis入门到实战-第十九弹

Redis实战热身Count-min-sketch篇 完整命令参考官网 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://redis.io/Redis概述 Redis是一个开源的&#xff08;采用BSD许可证&#xff09;&#xff0c;用作数据库、缓存、…

cuDNN——核心概念

在讨论graph和legacy API的细节之前&#xff0c;这一部分先介绍两者共同的核心概念。 cuDNN Handle cuDNN库暴露了一系列主机API&#xff0c;但是假设所有用到GPU的op&#xff0c;其必要的数据都可以直接从设备上访问。 使用cuDNN的应用必须先调用cudnnCreate()来初始化句柄…

【C/C++】C++中的四种强制类型转换

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

USART发送各种数据类型数据的原理及程序实现

硬件接线&#xff1a; 显示屏的SCA接在B11&#xff0c;SCL接在B10&#xff0c;串口的RX连接A9&#xff0c;TX连接A10。 新建Serial.c和Serial.h文件 在Serial.c文件中&#xff0c;实现初始化函数&#xff0c;等需要的函数&#xff0c;首先对串口进行初始化&#xff0c;只需要…

信创实力进阶,Smartbi再获华为云鲲鹏技术认证

日前&#xff0c;经华为技术有限公司评测&#xff0c;思迈特商业智能与数据分析软件Smartbi Insight V11与华为技术有限公司Kunpeng 920 Taishan 200完成并通过相互兼容性测试认证&#xff0c;成功再获华为云鲲鹏技术认证书&#xff0c;标志着Smartbi与华为云鲲鹏产业生态合作更…

http模块—http请求练习

题目要求&#xff1a;搭建如下http服务&#xff1a; 1.当浏览器向我们的服务器发送请求时&#xff0c;当请求类型是get请求&#xff0c;请求的url路径地址是/login。响应体结果是登录页面 2.当浏览器向我们的服务器发送请求时&#xff0c;当请求类型是get请求&#xff0c;请求…

物流智能蓝牙锁控设计方案

一、行业背景与需求分析 物流行业作为全球贸易和供应链管理的关键环节&#xff0c;其安全性和效率对整个经济体系的运作至关重要。随着电子商务的兴起和全球市场的一体化&#xff0c;物流行业正面临着前所未有的挑战&#xff0c;尤其是在货物安全、运输效率、成本控制和信息管…

C#学生信息成绩管理系统

一、系统功能描述 本系统包括两类用户&#xff1a;学生、管理员。管理员可以通过系统来添加管理员信息、修改管理员信息、添加学生信息、修改学生信息&#xff1b;开设课程、查询课程、录入成绩、统计成绩、修改成绩、修改个人密码等&#xff0c;而学生则可以通过系统来选择课…

干货分享:品牌如何通过社媒激发年轻人消费力?

随着年轻人的消费愈发理性&#xff0c;年轻人在消费时更偏向于熟人种草场景下的信任决策&#xff0c;社交媒体成为品牌吸引用户的必争之地。今天媒介盒子就来和大家聊聊&#xff1a;品牌如何通过社媒激发年轻人消费力。 一、 激发用户共鸣&#xff0c;与用户产生情感连接。 虽…

Midjourney辞典AIGC中英双语图文辞典+Midjourney提示关键词

完整内容下载&#xff1a;https://download.csdn.net/download/u010564801/89042077 完整内容下载&#xff1a;https://download.csdn.net/download/u010564801/89042077 完整内容下载&#xff1a;https://download.csdn.net/download/u010564801/89042077

哈希表(hash_table) 哈希存储 算法相关知识 稳定性 时间复杂度

哈希存储(散列存储) 为了快速定位数据 哈希表 哈希冲突 / 哈希矛盾 关键字不一样&#xff0c;但是映射之后结果一样 如何避免 哈希矛盾&#xff1f; 1、重新设计哈希函数&#xff0c;尽可能均匀散列分布在哈希表 2、开放定址法&#xff1a;向下寻找未存储的位置进行存放数…

aardio - 【库】godking.plusSkin 设置plus样式

库名&#xff1a;godking.plusSkin 库文件下载工具&#xff1a;http://chengxu.online/show.asp?softid272 使用本库&#xff0c;可以快速设置plus样式。主要针对按钮样式进行快速批量设置。 部分用法如下&#xff1a; import win.ui; /*DSG{{*/ var winform win.form(tex…

C++初学者:如何优雅地写程序

我喜欢C语言的功能强大&#xff0c;简洁&#xff0c;我也喜欢C#的语法简单&#xff0c;清晰&#xff0c;写起来又方便好用。 一、为什么不用C语言写程序。 C语言用来做题目&#xff0c;考试研究是很方便的&#xff0c;但是用来写程序做软件&#xff0c;你就会发现&#xff0c…

Android中运动事件的处理

1.目录 目录 1.目录 2.前言 3.程序演示 4.第二种程序示例 5.扩展 2.前言 触摸屏&#xff08;TouchScreen&#xff09;和滚动球&#xff08;TrackBall&#xff09;是 Android 中除了键盘之外的主要输入设备。如果需要使用触摸屏和滚动球&#xff0c;主要可以通过使用运动事…

[DS]Polar靶场web(一)

静以养心&#xff0c;宽以养气。 跟着Dream ZHO大神学专升安的一天 swp 直接dirb扫出.index.php.swp的目录 function jiuzhe($xdmtql){return preg_match(/sys.*nb/is,$xdmtql);//如果包含以 "sys" 开始&#xff0c;后跟任意字符直到 "nb" 的字符串&…

[XG] HTTP

我希望风起&#xff0c;而你好像更希望风停。 闲来无事&#xff0c;跟着Z3r4y-CSDN博客大神学一学web吧 [NewStarCTF 2023]Begin of HTTP 1.题目要求使用GET方式来给ctf参数传入任意值&#xff0c;那就传吧。 2.又让以POST方式来传递secert参数&#xff0c;并且要找一下参数…

python--字符串和常见的方法

1.字符串对象 字符串 " 字符串 " """ 字符串 """ 字符串 str() #全局函数&#xff0c;将一个类型转化为字符串 len(字符串) #获取字符串长度 while 和 for 循环&#xff0c;遍历字符串 案例一&#xff1a;查看字…

ubuntu系统下如何使用vscode编译和调试#小白入门#

编程环境&#xff1a;ubuntu系统为18.04.1&#xff0c;vscode版本为1.66.2 一、VSCode切换中文显示&#xff1a; 1、vscode安装完成后启动,在左侧externsions中搜索“简体中文”插件&#xff0c;并完成安装&#xff1a; 2、选择右下角齿轮形状的"Manage"&#xff…

记·汇编语言、C语言分别写并链接

电脑是64位的&#xff0c;汇编语言是AT&T风格。风格不同的汇编语言&#xff0c;汇编时的指令是不同的。在我学习过程中带来了挺多麻烦。 C语言内容。hello.c #include <stdio.h>//声明汇编编写的函数 extern void print_hello();int main() {// 调用汇编函数print_…