vue+springboot,easyexcel的excel文件下载

news2025/2/25 5:21:22

文章目录

    • 1.效果展示
      • 1.1 前端界面
      • 1.2 下载的excel
    • 2.思路介绍
    • 3.前端代码展示
    • 4.后端代码展示
    • 5.核心代码解释

1.效果展示

excel文件单一sheet,多sheet导出

本文主要介绍如何使用easyexcel ,配合前端导出Excel文件。同时提供Excel的两种导出形式:单一sheet,多sheet。

1.1 前端界面

在这里插入图片描述

1.2 下载的excel

单一sheet文件
在这里插入图片描述
多sheet文件
在这里插入图片描述

2.思路介绍

前端:直接通过window.location.href = url,跳转到对应url,借助浏览器直接下载文件。这样前端就无需做出额外的操作,也减少遇到bug的几率

后端:通过response返回的流数据,借助easyexcel的api:ExcelWriterBuilder write(OutputStream outputStream, Class head)返回流数据

3.前端代码展示

<div id="app">
    <el-row>
        <el-col :span="4">
            年级:<el-input v-model="year" placeholder="Input 1" disabled></el-input>
        </el-col>
        <el-col :span="4">
            组别:<el-input v-model="group" placeholder="Input 2" disabled></el-input>
        </el-col>
        <el-col :span="4">
            第几周:<el-input v-model="week" placeholder="请输入导出的周"></el-input>
        </el-col>
        <el-col :span="2">
            <el-button type="primary" @click="exportExcel(week)">导出</el-button>
        </el-col>
    </el-row>
    <el-row>
        <el-button type="primary" @click="exportExcel('全部')">全部导出</el-button>
    </el-row>
</div>

<script>
    new Vue({
        el: "#app",
        data: {
            year: '2023',
            group: 'java',
            week: '3',
        },
        methods: {
            exportExcel(week) {
                var year = this.year;
                var group = this.group;
                var url = address + `/sign/excel?year=${year}&group=${group}&week=${week}`;
                window.location.href = url;
            }
        },
    });
</script>

4.后端代码展示

controller

    /**
     * 返回excel导出数据
     */
    @GetMapping("/excel")
    public void getExcel(@RequestParam Map<String, Object> params, HttpServletResponse response) throws IOException {
        signInfoService.getExcel(params, response);
    }

service

    @Override
    public R getExcel(Map<String, Object> params, HttpServletResponse response) throws IOException {
        Object year = params.get("year");
        Object week = params.get("week");
        Object group = params.get("group");
        if (year == null) {
            year = "2023";
        }
        if (group == null) {
            group = "java";
        }
        // 请直接用浏览器或者用postman, 其它的入swagger容易报错
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");

            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode(group + "组-" + year + "级-" + week + "周" + "签到记录", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            // 判断是否需要导出全部的sheet
            String s = (String) week;
            if (s.equals("全部")) {
                // 指定文件
                ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), SignListDto.class).autoCloseStream(Boolean.FALSE).build();
                // 循环添加sheet
                for (int i = 2; i <= len; ++i) {
                    WriteSheet writeSheet = EasyExcel.writerSheet(i, "第" + i + "周").build();
                    // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
                    List<SignListDto> data = this.getSignListDto(year, i, group);
                    excelWriter.write(data, writeSheet);
                }
                // 关闭流数据
                excelWriter.finish();
            }else {
            	// 导出一个sheet文件
                EasyExcel.write(response.getOutputStream(), SignListDto.class).autoCloseStream(Boolean.FALSE).sheet("第" + week + "周")
                        .doWrite(this.getSignListDto(params));
            }
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = MapUtils.newHashMap();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(mapper.writeValueAsString(map));
        }
        return R.ok();
    }

dto

@Data
public class SignListDto {
    @ExcelProperty("用户id")
    private Integer id;
    @ExcelProperty("用户姓名")
    private String name;

    @ExcelProperty({"星期一", "签到"})
    private String up1;
    @ExcelProperty({"星期一", "签退"})
    private String out1;

    @ExcelProperty({"星期二", "签到"})
    private String up2;
    @ExcelProperty({"星期二", "签退"})
    private String out2;

    @ExcelProperty({"星期三", "签到"})
    private String up3;
    @ExcelProperty({"星期三", "签退"})
    private String out3;

    @ExcelProperty({"星期四", "签到"})
    private String up4;
    @ExcelProperty({"星期四", "签退"})
    private String out4;

    @ExcelProperty({"星期五", "签到"})
    private String up5;
    @ExcelProperty({"星期五", "签退"})
    private String out5;

    @ExcelProperty({"星期六", "签到"})
    private String out6;
    @ExcelProperty({"星期六", "签退"})
    private String up6;

    @ExcelProperty({"星期日", "签到"})
    private String up7;
    @ExcelProperty({"星期日", "签退"})
    private String out7;
}

@ExcelProperty("用户id")这个注解可以实现Java实体类的字段和excel的数据进行对应,数据填充时,Java数据就会赋值到对应列中
@ExcelProperty({"星期日", "签退"})这样的写法可以实现excel单元格的合并,具体效果如下
在这里插入图片描述

5.核心代码解释

前端
前端代码的核心只有一个:如何把文件下载的操作甩锅给浏览器,只要把活甩给浏览器,前端就不需要编写额外代码

new Vue({
        el: "#app",
        data: {...},
        methods: {
            exportExcel(week) {
                var year = this.year;
                var group = this.group;
                var url = address + `/sign/excel?year=${year}&group=${group}&week=${week}`;
				// 核心代码
                window.location.href = url;
            }
        },
    });

后端
后端的核心有2。1:如何传递流数据 2:如何操作easyexcel

1.如何传递流数据
通过HttpServletResponse response获取

response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.getOutputStream();

有了通向前端的流管道,我们就只需要操作easyexcel,制作excel文件

2.如何操作easyexcel

  • 单一sheet文件
// 这里需要设置不关闭流
EasyExcel.write(response.getOutputStream(), SignListDto.class).autoCloseStream(Boolean.FALSE).sheet("第" + week + "周")
                        .doWrite(this.getSignListDto(params));

其中,SignListDto.class,指定这个类去写excel。this.getSignListDto(params)返回excel所需的list数据:List<SignListDto>

  • 多sheet文件
// 创建ExcelWriter, 用于操作excel
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), SignListDto.class).autoCloseStream(Boolean.FALSE).build();
for (int i = 2; i <= len; ++i) {
	// 创建sheet
	WriteSheet writeSheet = EasyExcel.writerSheet(i, "第" + i + "周").build();
	// 查询数据
	List<SignListDto> data = this.getSignListDto(year, i, group);
	// 将数据写入sheet中
	excelWriter.write(data, writeSheet);
}
// 关闭IO
excelWriter.finish();

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

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

相关文章

《扩散模型 从原理到实战》Hugging Face (二)

第二章 Hugging Face简介 本章无有效内容 第三章 从零开始搭建扩散模型 有时候&#xff0c;只考虑事情最简单的情况反而更有助于理解其工作原理。本章尝试从零开始搭建廓庵模型&#xff0c;我们将从一个简单的扩散模型讲起&#xff0c;了解其不同部分的工作原理&#xff0c;…

Learn Prompt-ChatGPT 精选案例:学习各国语言

过去&#xff0c;我们学语言需要花费很多时间来学习各种材料&#xff0c;再联系老师修改口语、作文等&#xff0c;十分费时费力。有了 ChatGPT 之后&#xff0c;我们就相当于有一个免费的&#xff0c;实时反馈的语言学习助手&#xff0c;大大节省了我们的时间。下面我将以英文的…

如何搭建游戏平台?

搭建游戏平台是一个复杂的任务&#xff0c;涉及多个方面的工作。下面是一些关键步骤和注意事项&#xff0c;以帮助您搭建游戏平台&#xff1a; 平台开发&#xff1a;开发游戏平台的关键部分&#xff0c;包括网站或应用程序的开发、数据库设计、用户界面设计、游戏上传和管理工具…

ipad触控笔有必要买原装吗?开学推荐平价好用的电容笔

在日常生活中&#xff0c;电容笔的用途非常广泛&#xff0c;无论是配上电脑&#xff0c;还是配上iPad平板&#xff0c;亦或是配上手机&#xff0c;都是非常不错的办公利器。首先要明确自己什么使用需求&#xff0c;然后才能选择适合自己需要的电容笔。苹果的Pencil拥有独一无二…

VIOOVI干货分享:什么是SOP?它的六要素是什么?

什么是SOP&#xff0c;SOP就是标准化的作业程序。它以文档的形式&#xff0c;详细的描述操作人员在生产操作过程中的操作步骤和应当遵守的事项&#xff1b;是操作人员的操作说明书&#xff1b;也是检查员指导工作的依据。 SOP的六要素是&#xff1a; 物料名称和数量&#xff1…

linux 解决发现不到的 内存占用率

1、问题浮现 项目做久了&#xff0c;你往往会遇到一些稀奇古怪的问题。下面咱就来聊聊关于内存无故使用率变大的真相。事情是这样的&#xff0c;最近一个客户的服务器&#xff0c;内存使用率在90%左右&#xff0c;这很不正常&#xff0c;导致某云的云安全中心一直报警&#xff…

Jenkins结合Gitlab,实现镜像构建及推送

docker-compose jenkins的docker-compose目录为为/home/jenkins&#xff0c;这个后面写脚本的时候需要对应上 version: 3 services:docker_jenkins:restart: alwaysimage: jenkins/jenkins:ltscontainer_name: docker_jenkinsprivileged: true ports:- 8080:8080- 50000:5000…

面试官:ES6中新增的Set、Map两种数据结构怎么理解?

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 一、Set 增删改查 add() delete() has() clear() 遍历 二、Map 增删改查 size set() get() has() del…

深度学习——线性神经网络二

深度学习——线性神经网络二 文章目录 前言一、softmax回归1.1. 分类问题1.2. 网络架构1.3. 全连接层的参数开销1.4. softmax运算1.5. 小批量样本的向量化1.6. 损失函数1.6.1. 对数似然1.6.2. softmax及其导数1.6.3. 交叉熵损失 1.7. 信息论基础1.7.1 熵1.7.2. 信息量1.7.3. 重…

论文阅读-Group-based Fraud Detection Network on e-Commerce Platforms

目录 摘要 1 Introduction 2 BACKGROUND AND RELATED WORK 2.1 Preliminaries 2.2 Related Works 3 MODEL 3.1 Structural Feature Initialization 3.2 Fraudster Community Detection 3.3 Training Objective 4 EXPERIMENT 4.1 Experimental Setup 4.2 Prediction …

征战MINI学习路线

征战MINI学习路线 征战MINI与ACX720开发板的具体差异 1. 时钟电路 管脚约束一样&#xff0c;仅仅是位号名称不同&#xff0c;ACX720的晶振位号是U2&#xff0c;征战MINI的位号是X1&#xff0c;如下图所示&#xff1a; 2. 拨码开关电路 管脚约束一样&#xff0c;仅仅是位…

Spring高手之路5,Dubbo服务注册与发现(文末送书)

目录 一、介绍1、介绍 Dubbo 服务注册与发现的基本概念和重要性2、阐述 Dubbo 服务注册与发现的实现方式和应用场景 二、Dubbo 服务注册与发现的架构设计1、Dubbo 服务注册与发现的总体架构设计。2、Dubbo 服务提供方的注册与发现设计3、Dubbo 服务消费者端的注册与发现设计 三…

iTOP-2K1000开发板拷贝镜像到固态

在本章的刚开始&#xff0c;我们就提到了烧写系统到固态硬盘我们需要使用 U 盘启动作为桥梁&#xff0c;把系统镜像以及系统配置文件拷贝到固态硬盘里面。所以我们需要先准备一个可以成功系统的 U 盘来启动开发板。那此时 U 盘里面是不是就有系统呢&#xff1f;所以这一步我就要…

【python基础】变量

.变量-理解 编程本质就是通过一定的逻辑&#xff0c;去操纵数据&#xff0c;来达到我们的设想。 变量作为数据的载体&#xff0c;在程序中经常会被用到。与变量相联系的还有一个名词叫数据类型&#xff0c;如何理解数据类型-变量-数据三者之间的关系呢&#xff1f; 我们通过文…

进程同步与互斥

目录 进程同步与互斥&#xff08;1&#xff09; 第一节、进程间相互作用 一、相关进程和无关进程 二、与时间有关的错误 第二节、进程同步与互斥 一、进程的同步 二、进程的互斥 三、临界区 进程同步与互斥&#xff08;2&#xff09; 三、信号量与P、V操作的物理含义…

Git基础操作

前言 本文会向您介绍如何安装git&#xff0c;以及快速地上手add&#xff0c;commit&#xff0c;push&#xff0c;版本回退操作 基础配置 关于windous上的安装git官网已经介绍的很清楚了&#xff0c;您可以直接点入链接windows安装 如果你的平台是centos&#xff0c;以centos…

【树形 DP】树形 DP 的通用思路

题目描述 这是 LeetCode 上的 「310. 最小高度树」 &#xff0c;难度为 「中等」。 Tag : 「树形 DP」、「DFS」、「动态规划」 树是一个无向图&#xff0c;其中任何两个顶点只通过一条路径连接。 换句话说&#xff0c;一个任何没有简单环路的连通图都是一棵树。 给你一棵包含 …

24.(地图工具篇)geoserver热力图层SLD样式效果

地图之家总目录(订阅之前必须详细了解该博客) 示例效果 一:SLD代码 <?xml version="1.0" encoding="ISO-8859-1"?><StyledLayerDescriptor version="1.0.0"xsi:schemaLocation

【UE 粒子练习】05——创建光束类型粒子

效果 步骤 1. 新建一个材质&#xff0c;这里命名为“Mat_Beam” 设置材质域为表面&#xff0c;混合模式为半透明&#xff0c;着色模型为无光照 材质节点如下&#xff1a; 2. 新建一个粒子系统&#xff0c;命名为“P_Beam” 打开“P_Beam”&#xff0c;在发射器中新建一个光束数…

无线振弦采集仪应用隧道安全监测的方案解析

无线振弦采集仪应用隧道安全监测的方案解析 隧道是交通建设中重要的组成部分&#xff0c;安全监测是保障隧道使用安全的重要手段。无线振弦采集仪可以对隧道进行实时、连续的振动监测&#xff0c;提供精确的数据分析和预警&#xff0c;是隧道安全监测的有效工具。 无线振弦采…