springDatajpa动态sql根据时间范围将数据导出为excel并使用vue的按钮去触发

用到的技术点:
1.springDatajpa
2.EasyExcel
3.数据库
4.vue

前端实现:
1.创建按钮(点击此按钮弹出填写导出条件的弹出框)

 <el-button type="primary" round @click="dialogVisible = true"><svg-icon icon-class="jurassic" />&nbsp;&nbsp;导出</el-button>
 //================================
  <el-dialog
      title="导出条件"
      :visible.sync="dialogVisible"
      width="30%"
    >
      <el-form ref="exportConditionForm" :model="exportCondition" :rules="exportConditionRules" label-width="100px" class="demo-ruleForm">
        <el-form-item label="登录账号" prop="account">
          <el-input v-model="exportCondition.account" />
        </el-form-item>
        <el-form-item label="姓名" prop="name">
          <el-input v-model="exportCondition.name" />
        </el-form-item>
        <el-form-item label="登录IP地址" prop="ip">
          <el-input v-model="exportCondition.ip" />
        </el-form-item>
        <el-form-item label="登录时间" prop="time">
          <el-date-picker
            v-model="exportCondition.time"
            type="daterange"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :default-time="['00:00:00', '23:59:59']"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="exportButtonEvent">导出</el-button>
      </span>
    </el-dialog>

2.为导出按钮添加导出事件(这里是下载的关键)

 exportButtonEvent() {
      const shuju = this.exportCondition
      axios({
        method: 'post',
        //这里是我的后端接口地址改成你的,这里会涉及到跨域的
        //问题1.使用注解形式解决2.重写addCorsMappings方法3.前   
        //端处理
        //其他地方就不用改了
        url: window.wgParameter.VUE_APP_FILE_USER_API + '/loginformation/query/exportuserinfor',
        data: shuju,
        responseType: 'arraybuffer'
      }).then(res => {
        const name = res.headers['content-disposition']
        if (res.size === 0) { // 如果返回是空的
          this.$message({
            message: '报错了',
            type: 'warning'
          })
        } else { // 返回不为空
          if (!!window.ActiveXObject || 'ActiveXObject' in window) {
            window.navigator.msSaveOrOpenBlob(res, '计算结果.xlsx')
          } else {
            const url = window.URL.createObjectURL(

              new Blob([res.data], {

                type: 'application/octet-stream'
              })

            )

            const link = document.createElement('a')

            link.href = url

            link.setAttribute(

              'download', decodeURI(name.split("attachment;filename*=utf-8''")[1], 'utf-8')

            )
            link.click()
          }
        }
      }).catch(error => {
        this.$message({
          message: '报错了:' + error,
          type: 'warning'
        })
      })
    }

后端实现:
1.建表,用EasyExcel的注解(@ExcelProperty)标记表中属性(easyExcel的用法见其官网)

用来对应后台数据的实体类(在其中规定了excel的格式标题位置)

package com.zgy.handle.userService.model.loginformation;

import com.alibaba.excel.annotation.ExcelProperty;
import com.zgy.handle.userService.model.dto.BaseDTO;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Embeddable;

@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LogInformationDto extends BaseDTO {
    @ExcelProperty(value = "账号", index = 0)
    @ApiModelProperty("账号")
    String account;
    @ExcelProperty(value = "姓名", index = 1)
    @ApiModelProperty("姓名")
    String name;
    @ApiModelProperty("ip地址")
    @ExcelProperty(value = "ip地址", index = 2)
    String ip;
    @ApiModelProperty("登录时间/操作时间")
    @ExcelProperty(value = "登录时间/操作时间", index = 3)
    String time;
    /**
     * 类型
     * 1--登录
     * 2--操作
     */
    @ApiModelProperty("类型")
    @ExcelProperty(value = "类型", index = 4)
    Integer type;
    @ApiModelProperty("模块名")
    @ExcelProperty(value = "模块名", index = 5)
    String modulename;
}

封装前台参数的实体类

package com.zgy.handle.userService.model.loginformation;

import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExportLoginformation {
    @ApiModelProperty("账号")
    String account;
    @ApiModelProperty("姓名")
    String name;
    @ApiModelProperty("ip地址")
    String ip;
    @ApiModelProperty("开始时间-结束时间")
    String[] time;
}

2.写业务处理层代码(用动态sql查数据,之后用Easyexcel将数据以excel的格式写出到response响应体中供前端下载用)

  @Override
    public void exportUserInfor(HttpServletResponse response, ExportLoginformation exportLoginformation) {
        //动态查询
        Specification<LogInformation> sf = (Specification<LogInformation>) (root, query, cb) -> {
            //用于添加所有查询条件
            List<Predicate> p = new ArrayList<>();
            if (!exportLoginformation.getIp().isBlank()) {
                Predicate p1 = cb.equal(root.get("ip").as(String.class), exportLoginformation.getIp());
                p.add(p1);
            }
            if (!exportLoginformation.getName().isBlank()) {
                Predicate p2 = cb.equal(root.get("name").as(String.class), exportLoginformation.getName());
                p.add(p2);
            }
            if (!exportLoginformation.getAccount().isBlank()) {
                Predicate p3 = cb.equal(root.get("account").as(String.class),exportLoginformation.getAccount() );
                p.add(p3);
            }
            if(exportLoginformation.getTime().length>0){
                String[] time = exportLoginformation.getTime();
                Date startDate = null;
                Date endDate = null;
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
                try {
                    if (StringUtils.isNotBlank(time[0])) {
                        startDate = dateFormat.parse(time[0]);
                    }

                    if (StringUtils.isNotBlank(time[1])) {
                        endDate = dateFormat.parse(time[1]);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                    return null;
                }
                Predicate p4 = null;
                if (startDate != null && endDate != null) {
                    p4 = cb.between(root.get("time").as(Date.class), startDate, endDate);

                } else if (startDate != null) {
                    p4 = cb.greaterThanOrEqualTo(root.get("date").as(Date.class), startDate);

                } else {
                    p4 = cb.lessThanOrEqualTo(root.get("date").as(Date.class), endDate);
                }
                p.add(p4);
            }
            Predicate[] pre = new Predicate[p.size()];
            Predicate and = cb.and(p.toArray(pre));     //查询条件 and
            //Predicate or = cb.or(p.toArray(pre));       //查询条件 or
            query.where(and);       //添加查询条件

            //设置排序
            List<Order> orders = new ArrayList<>();
            orders.add(cb.desc(root.get("time").as(Date.class)));       //倒序
//            orders.add(cb.asc(root.get("username")));   //正序
            return query.orderBy(orders).getRestriction();
        };
        List<LogInformation> all = logInformationQueryReposition.findAll(sf);
        List<LogInformationDto> logInformationDtos = logInformationMapper.toLogInformationDtoList(all);
        String fileName =URLEncoder.encode("用户登录信息-" + System.currentTimeMillis() + ".xlsx", StandardCharsets.UTF_8).replaceAll("\\+", "%20");

        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        // 如果这里想使用03 则 传入excelType参数即可
        // 设置响应头
        response.setHeader("Access-Control-Expose-Headers", "Content-disposition");
        response.setHeader("Content-disposition","attachment;filename*=utf-8''"+fileName);
        try {
            EasyExcel.write(response.getOutputStream(), LogInformationDto.class).sheet("用户登录信息").doWrite(logInformationDtos);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

上面的业务逻辑:用户根据ip,账号,用户名,要查询的一个时间范围(开始时间,结束时间)去动态的进行数据查询,并通过数据库中的时间字段排序fileName(换成你的文件名) EasyExcel.write(response.getOutputStream(), LogInformationDto.class).sheet("用户登录信息").doWrite(logInformationDtos);其中LogInformationDto.class是你的数据封装类行用户登录信息是excel中sheet页的名字logInformationDtos你从数据库中查出的数据

后端解决跨域的问题

package com.zgy.handle.userService.confg.cros;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CORSConfiguration implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // `/loginformation/query/exportuserinfor`这是你的接口
        //地址没有`http://ip:端口`的部分
        registry.addMapping("/loginformation/query/exportuserinfor")
                .allowedMethods("*")
                 .allowedOrigins("*")
                .allowedHeaders("*");
    }


}

前端传来的时间格式的转换这块儿可能会报错建议使用catgpt(BIto插件)解决问题
将你的错误告诉他就好了,我的代码就是问过他后解决的错误
在这里插入图片描述
.as(类型)这个在每个属性的断言中都要加否则会报与期望的类型不匹配的错误

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么是Session

1、web中什么是会话 &#xff1f; 用户开一个浏览器&#xff0c;点击多个超链接&#xff0c;访问服务器多个web资源&#xff0c;然后关闭浏览器&#xff0c;整个过程称之为一个会话。 2、什么是Session &#xff1f; Session:在计算机中&#xff0c;尤其是在网络应用中&…

MySQL数据同步到ES的4种解决方案

一、背景 大家应该都在各种电商网站检索过商品&#xff0c;检索商品一般都是通过什么实现呢&#xff1f;搜索引擎Elasticsearch。那么问题来了&#xff0c;商品上架&#xff0c;数据一般写入到MySQL的数据库中&#xff0c;那么用于检索的数据又是怎么同步到Elasticsearch的呢&…

分布式定时任务框架 PowerJob

业务背景 1.1 为什么需要使用定时任务调度 &#xff08;1&#xff09;时间驱动处理场景&#xff1a;整点发送优惠券&#xff0c;每天更新收益&#xff0c;每天刷新标签数据和人群数据。 &#xff08;2&#xff09;批量处理数据&#xff1a;按月批量统计报表数据&#xff0c;批…

使用nodejs操作postgresql

环境准备 1 navicat premium 2 postgresql 14 装完上述软件后&#xff0c;远程连接上之后如下&#xff1a; 自己建立一个用户表users,然后随机生成一些数据即可 步骤 这里我将项目放到了gticode里&#xff0c;可以下载下来使用 https://gitcode.net/wangbiao9292/nodejs-p…

数据技术在金融行业有哪些应用_光点科技

随着信息技术的迅猛发展&#xff0c;大数据技术逐渐成为金融行业的重要工具。大数据技术的应用&#xff0c;不仅可以提高金融机构的运营效率&#xff0c;还能够提供更准确的风险评估和预测&#xff0c;从而为投资者和决策者提供更好的决策依据。 那么&#xff0c;大数据技术在…

Keil MDK编程环境下的 STM32 IAP下载(学习笔记)

IAP的引入 不同的程序下载方式 ICP ICP(In Circuit Programing)。在电路编程&#xff0c;可通过 CPU 的 Debug Access Port 烧录代码&#xff0c;比如 ARM Cortex 的 Debug Interface 主要是 SWD(Serial Wire Debug) 或 JTAG(Joint Test Action Group)&#xff1b; ISP ISP(I…

【VUE】ElementUI实现表格拖拽功能及行大图预览

一. 背景 elementui没自带的拖拽排序功能&#xff0c;所以需要借助第三方插件sortablejs 二. 步骤 安装 npm install sortablejs --save 引入 import Sortable from ‘sortablejs’ template文件应用 row-key填写唯一标识 id"dragTable"是为了通过document找到…

C++——命名空间(namespace)

目录 1. C语言命名冲突 2. 命名空间定义 3. 命名空间使用 可能大家在看别人写的C代码中&#xff0c;在一开始会包这个头文件&#xff1a;#include<iostream> 这个头文件等价于我们在C语言学习到的#include<stdio.h>&#xff0c;它是用来跟我们的控制台输入和输出…

利用Django路由项的别名(name)对路由进行反向解析

在Django的函数path()中&#xff0c;可以给一条路由进行命名&#xff0c;然后在视图函数或模板HTML文件中进行调用&#xff0c;这样的好处是&#xff1a;只要路由的name不变&#xff0c;那么修改了URL具体的路由&#xff0c;也不用去更改视图函数或模板HTML中的相关代码&#x…

LNMP服务搭建

目录 一、安装Nginx 1.关闭防火墙和安全机制 2.安装依赖包 3.创建运行用户 4.编译安装并安装 5.优化路径 6. 添加 Nginx 系统服务 7.赋权并重启服务 二、安装Mysql数据库 1、安装Mysql环境依赖包 2.创建运行用户 3.编译安装 4.修改mysql 配置文件 5.更改mysql安装目录和…

Linux服务器同步Windows目录同步-rsync

前言 最近需要&#xff0c;Linux的服务器同步Windows的一个目录。查了下&#xff0c;大概有三种方法&#xff1a;网盘同步&#xff1b;rsync同步&#xff1b;挂载目录。 网盘同步&#xff0c;可以选择搭建一个Nextcloud 。但是问题在于&#xff0c;我需要的是&#xff0c;客户…

前端开发两年半,我裸辞了

☀️ 前言 一晃两年半过去了&#xff0c;我离开了我的第一份前端开发工作&#xff0c;当你看到这篇文章&#xff0c;我已经离职两个月了&#xff0c;目前仍在艰难求职中&#xff0c;想记录分享一下我的经历&#xff0c;感兴趣的可以继续往下看&#xff0c;希望能给大家一些启示…

Objective-C 混用UITabBar与UINavigation

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 混用UITabBar与UINavigation做app&#xff0c;tab和nav&#xff0c;有时候显示有时候…

03 Web全栈 浏览器内置对象/事件/ajax

浏览器是一个JS的运行时环境&#xff0c;它基于JS解析器的同时&#xff0c;增加了许多环境相关的内容&#xff0c;用一张图表示各个运行环境和JS解析器的关系如下&#xff1a; 我们把常见的&#xff0c;能够用JS这门语言控制的内容称为一个JS的运行环境&#xff0c;常见的运行环…

专业科普:什么是单片机?

一、什么是单片机 单片机诞生于20世纪70年代末&#xff0c;它是指一个集成在一块芯片上的完整计算机系统。单片机具有一个完整计算机所需要的大部分部件&#xff1a;CPU、内存、内部和外部总线系统&#xff0c;目前大部分还会具有外存。同时集成诸如通讯接口、定时器&#xff…

Edge浏览器可以多开吗?

问答链接&#xff1a;Edge浏览器可以多开吗&#xff1f; 可以。 如果你的edge浏览器是默认路径安装的&#xff0c;那么打开命令提示符窗口输入以下两条命令即可启动一个数据完全隔离的edge浏览器。 mkdir C:\logs001 "C:\Program Files (x86)\Microsoft\Edge\Applicati…

【宝塔服务器】宝塔通过composer安装TP依赖

屡屡碰壁&#xff0c;安装一个项目&#xff0c;发现没有依赖&#xff0c;需要使用composer安装&#xff0c;没接触过&#xff0c;找了网上也没攻略&#xff0c;自己弄了后有以下问题&#xff0c;经过调整解决了&#xff1a; 报错1:没有安装fileinfo扩展 Loading composer rep…

Linux下RPM软件包管理

目录 1、软件包管理介绍1.1、软件包分类1.2、源码包1.3、RPM包 2、RPM包管理-包命名和依赖性2.1、RPM命名规则2.2、RPM包依赖性 3、RPM包管理-安装升级和与卸载3.1、包全名与包名3.2、RPM安装3.3、RPM包升级3.4、卸载 4、RPM包管理-查询4.1、查询是否安装4.2、查询软件包详细信…

Java集合相关问题

java集合框架体系 数据结构 算法复杂度分析 时间复杂度分析&#xff1a;对代码运行时间所消耗时间多少进行分析空间复杂度分析&#xff1a;对代码运行所占用的内存的大小进行分析 时间复杂度 时间复杂度分析&#xff1a;来评估代码的执行耗时 假如执行每行代码的执行耗时一…

阿里云服务器ping不通如何解决?

阿里云服务器ping不通&#xff1f;什么原因&#xff1f;在安全组中允许【全部 ICMP(IPv4)】&#xff0c;当然阿里云服务器禁ping也是通过配置安全组的ICMP规则来实现的&#xff0c;阿里云服务器网来详细说下安全组开通ping功能教程&#xff1a; 目录 阿里云服务器ping不通的解…