Easy Excel生成复杂下Excel模板(下拉框)给用户下载

news2024/9/21 0:46:07

引言

文件的下载是一个非常常见的功能,也有一些非常好的框架可以使用,这里我们就介绍一种比较常见的场景,下载Excel模版,导入功能通常会配有一个模版下载的功能,根据下载的模版,填充数据然后再上传。

需求

如图所示用户下载如下模版,模版中的地区是从数据库中读出来的。
在这里插入图片描述

分析

如果模版都是固定的内容,这种比较简单,我们可以直接把模版上传到我们的文件服务器,用户下载的时候可以直接在文件服务器上下载,或者是把文件放到我们的工程里面,直接读取文件然后以流的方式返回给前端,用户直接下载。
这里比较麻烦点的就是这个模版的内容不是固定的,需要在库里查询出来,写到excel然后在返给前端。同时这个文件又有一定的样式,一般有样式的文件,我们可以根据模版填充,而不是把说有的样式都用程序代码写,程序代码写这种样式会很麻烦。所以我们这里用的方式就是填充模版

准备模版

把准备好的模版放到我们工程里面,创建文件夹template 并把文件夹设置为resource,设置为resoucre后该文件夹下面的文件在mvn打包的时候回合我们的java类打在同一个路径下,方便我们获取文件
在这里插入图片描述
在这里插入图片描述

编写下拉选项的handler

public class SelectSheetWriteHandler implements SheetWriteHandler {

    private String[] list;
    private int firstRow;
    private int lastRow;
    private int firstCol;
    private int lastCol;

    public SelectSheetWriteHandler(String[] list, int firstRow, int lastRow, int firstCol, int lastCol) {
        this.list = list;
        this.firstRow = firstRow;
        this.lastRow = lastRow;
        this.firstCol = firstCol;
        this.lastCol = lastCol;
    }

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        // 区间设置 第一列第一行和第二行的数据。由于第一行是头,所以第一、二行的数据实际上是第二三行
        CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
        DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();
        DataValidationConstraint constraint = helper.createExplicitListConstraint(list);
        DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
        dataValidation.setShowErrorBox(true);
        writeSheetHolder.getSheet().addValidationData(dataValidation);
    }
}

下载的方法

 public void export(HttpServletResponse response) throws IOException {
        //模板文件
        InputStream templateFile = TenantInsuranceFundServiceImpl.class.getResourceAsStream("/五险一金导入模板.xlsx");
        //导出后的文件名
        String fileName =  "五险一金导入模板";
        List<BaseDictionaryVO> baseDictionaryVOS = dictionaryService.queryDictionaryDetail(DictionaryEnum.AREA.getCode(), DictionaryEnum.AREA.getName());
        Set<String> areaNameList = new HashSet<>();
        if(!CollectionUtils.isEmpty(baseDictionaryVOS)){
            areaNameList = baseDictionaryVOS.stream().map(BaseDictionaryVO::getName).collect(Collectors.toSet());
        }
        SelectSheetWriteHandler selectSheetWriteHandler = new SelectSheetWriteHandler(areaNameList.toArray(new String[areaNameList.size()]), 2, 5000, 0, 0);
        //写入
        ExcelWriter excelWriter = null;
        try {
            //流输出
            excelWriter = EasyExcel.write(response.getOutputStream())
                    .withTemplate(templateFile)
                    .registerWriteHandler(selectSheetWriteHandler)
                    .build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            // 直接写入list数据 这里没有数据需要填写直接一个空集合
            excelWriter.fill(Arrays.asList(),  writeSheet);
            //浏览器下载操作
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码
            fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            excelWriter.finish();
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("code", "1");
            map.put("message", "下载模板失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        } finally {
            // 千万别忘记关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }

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

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

相关文章

【MATLAB第82期】基于MATLAB的季节性差分自回归滑动平均模型SARIMA时间序列预测模型含预测未来

【MATLAB第82期】基于MATLAB的季节性差分自回归滑动平均模型SARIMA时间序列预测模型含预测未来 一、模型介绍 1、模型简介 季节性差分自回归移动平均模型&#xff08;Seasonal Autoregressive Integrated Moving Average Model, SARIMA&#xff09;&#xff0c;又称为周期性…

指针进阶篇

指针的基本概念&#xff1a; 指针是一个变量&#xff0c;对应内存中唯一的一个地址指针在32位平台下的大小是4字节&#xff0c;在64位平台下是8字节指针是有类型的&#xff0c;指针类型决定该指针的步长&#xff0c;即走一步是多长指针运算&#xff1a;指针-指针表示的是两个指…

SQL注入学习(配合SQLi-lab靶场)

前提条件&#xff1a; 在进行sql注入时&#xff0c;首先要确定网页有注入点&#xff0c;一般在URL地址栏中&#xff0c;或者含有输入框的地方会有 SQL注入步骤&#xff1a; 1、判断注入类型 首先判断是什么类型的注入&#xff0c;用id1 and 11 和id1 and 12 判断是数字类型注…

Redis设计与实现之整数集合

目录 一、内存映射数据结构 二、整数集合 1、整数集合的应用 2、数据结构和主要操作 3、intset运行实例 创建新intset 添加新元素到 intset 添加新元素到 intset&#xff08;不需要升级&#xff09; 添加新元素到 intset (需要升级) 4、升级 升级实例 5、关于升级 …

25.Java程序设计-基于SSM框架的微信小程序校园求职系统的设计与实现

1. 引言 1.1 背景 介绍校园求职系统的背景&#xff0c;说明为什么设计这个系统以及系统的重要性。 1.2 研究目的 阐述设计基于SSM框架的微信小程序校园求职系统的目标和意义。 2. 需求分析 2.1 行业背景 分析校园求职行业的特点和需求&#xff0c;以及目前市场上同类系统…

Spring Boot SOAP Web 服务端和客户端

一. 服务端 1. 技术栈 JDK 1.8&#xff0c;Eclipse&#xff0c;Maven – 开发环境SpringBoot – 基础应用程序框架wsdl4j – 为我们的服务发布 WSDLSOAP-UI – 用于测试我们的服务JAXB maven 插件 – 用于代码生成 2.创建 Spring Boot 项目 添加 Wsdl4j 依赖关系 编辑pom…

化学方程式小程序

brief introduction 相信大家上中学时都会被化学方程式折腾得死去活来&#xff0c;尤其是配平&#xff0c;怎么也算不对数字。于是我写出了这款近200行的自动配平程序&#xff0c;这是不是你们黑暗化学中的一丝光亮呢&#xff1f; usage 正常化学式输入&#xff0c;每一种物…

智慧农业大数据可视化UI,数据展示平台(免费可视化大屏模版PS资料)

大屏幕展示方式可以实现信息的直观呈现与交互操作&#xff0c;使农业生产者能够一目了然地掌握有关农情、天气、土壤等数据信息&#xff0c;从而科学决策。智慧农业大数据可视化大屏是提升农业生产效益的一种重要工具。 现分享亩产效益指标、农业大数据可视化、农业数据展示平…

基于EasyExcel的数据导入导出

前言&#xff1a; 代码复制粘贴即可用&#xff0c;主要包含的功能有Excel模板下载、基于Excel数据导入、Excel数据导出。 根据实际情况修改一些细节即可&#xff0c;最后有结果展示&#xff0c;可以先看下结果&#xff0c;是否是您想要的。 台上一分钟&#xff0c;台下60秒&a…

QT Widget - 随便画个圆

简介 实现在界面中画一个圆, 其实目的是想画一个LED效果的圆。代码 #include <QApplication> #include <QWidget> #include <QPainter> #include <QColor> #include <QPen>class LEDWidget : public QWidget { public:LEDWidget(QWidget *pare…

前端传递参数,后端如何接收

目录 简单参数 传递方式 获取方式一 获取方式二 相关注解 实体参数 数组集合参数 传递方式 相关注解 获取方式一 获取方式二 日期参数 传递方式 相关注解 获取方式 json参数 传递方式 相关注解 获取方式 路径参数 传递方式 相关注解 获取方式 传递多个…

【Java系列】详解多线程(三)—— 线程安全(上篇)

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【Java系列专栏】【JaveEE学习专栏】 本专栏旨在分享学习Java的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 一…

心理测试网站源码,知己心理React心理健康测试

源码介绍 React心理健康测试网站源码&#xff0c;帮助需要的人更好地了解自已的心理健康状态和人格特征。 React可以在Vite中启用HMR&#xff0c;并且包含了几人EsLint规则。只需要使用react antd-mobile即可 轻松部署完成。

【JAVA日志框架】JUL,JDK原生日志框架详解。

前言 Java日志体系混乱&#xff1f;Java日志框架系列&#xff0c;清晰简洁整理好整个Java的日志框架体系。第一篇&#xff0c;JDK原生日志框架——JUL。 目录 1.概述 2.日志级别 3.配置 4.继承关系 1.概述 日志框架的核心问题&#xff1a; 日志是用来记录应用的一些运行…

C++ Qt开发:Tab与Tree组件实现分页菜单

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍tabWidget选择夹组件与TreeWidget树形选择组件…

Swift 响应式编程:简化 KVO 观察与 UI 事件处理 | 开源日报 No.110

ReactiveX/RxSwift Stars: 23.8k License: MIT RxSwift 是 Reactive Extensions 标准的 Swift 特定实现&#xff0c;它提供了 Observable 接口来表达计算的通用抽象。该项目旨在为 Rx API 提供真正以 Swift 为先的 API&#xff0c;并允许轻松地组合异步操作和数据流。其主要功…

K8s投射数据卷

目录 一.Secret 1.secret介绍 2.secret的类型 3.创建secret 4.使用secret 环境变量的形式 volume数据卷挂载 二ConfigMap 1.创建ConfigMap的方式 2.使用ConfigMap 2.1作为volume挂载使用 2.2.作为环境变量 三.Downward API 1.以环境变量的方式实现 2.Volume挂载 一.S…

Linux 中使用 docker 安装 Elasticsearch 及 Kibana

Linux 中使用 docker 安装 Elasticsearch 及 Kibana 安装 Elasticsearch 和 Kibana安装分词插件 ik_smart 安装 Elasticsearch 和 Kibana 查看当前运行的镜像及本地已经下载的镜像&#xff0c;确认之前没有安装过 ES 和 Kibana 镜像 docker ps docker images从远程镜像仓库拉…

HarmonyOS后台代理提醒

后台代理提醒 简介 随着生活节奏的加快&#xff0c;我们有时会忘记一些重要的事情或日子&#xff0c;所以提醒功能必不可少。应用可能需要在指定的时刻&#xff0c;向用户发送一些业务提醒通知。例如购物类应用&#xff0c;希望在指定时间点提醒用户有优惠活动。为满足此类业…

redis:四、双写一致性的原理和解决方案(延时双删、分布式锁、异步通知MQ/canal)、面试回答模板

双写一致性 场景导入 如果现在有个数据要更新&#xff0c;是先删除缓存&#xff0c;还是先操作数据库呢&#xff1f;当多个线程同时进行访问数据的操作&#xff0c;又是什么情况呢&#xff1f; 以先删除缓存&#xff0c;再操作数据库为例 多个线程运行的正常的流程应该如下…