excel自定义导出实现(使用反射)

前言

项目中接到需求,需要对导出的字段进行自定义导出 ,用户可在前端选择自定义导出的字段(如图),实现过程做以下记录,仅供参考;
在这里插入图片描述

思路

跟前端约定好所有要导出的字段名称(headName)跟对应的实体名称(fieldName),勾选导出的字段后就传字段到后端,后端根据反射去匹配要导出的字段最后输出;

实现

  • 约定导出的字段名称、实体名
    在这里插入图片描述
  • 导出字段实体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ApproveExcelHeader {
    /**
     * 要导出的字段名称
     */
    private String fieldName;
    /**
     * 要导出的表头名称
     */
    private String headName;
    /**
     * 是否导出
     */
    private String disabled;
}
  • 定义接口
 /**
     * 根据前端传入的字段自定义导出的列
     * @param dto
     * @throws IOException
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    @ApiOperation("导出")
    @PostMapping("/exportExcel")
    public void exportExcel(@RequestBody aqglRiskQuarterApproveDto dto, HttpServletResponse response) throws IOException, NoSuchFieldException, IllegalAccessException {
        Assert.notNull(dto.getRiskCycle(), "周期不能为空!");
        List<ApproveExcelHeader > exportFiledList =dto.getExportFiled();
        List<String> headNamelist = exportFiledList.stream().map(ApproveExcelHeader ::getHeadName).collect(Collectors.toList());
        if(headNamelist.isEmpty()){
            throw new BusinessException("要导出的字段不能为空!");
        }
        List<Map<String, Object>> exportList = approveService.riskQuarterRecognitionExportList(dto);
        List<String> headNameList = exportFiledList.stream().map(ApproveExcelHeader ::getHeadName).collect(Collectors.toList());
        String fileName ="导出文件名";
        ExportUtils.dynamicsExportExcel(fileName, headNameList, exportList,response);

    }
  • 处理类
  • 此处主要根据前端传进来的字段去查询出的字段利用反射匹配;
 public List<Map<String, Object>>riskQuarterRecognitionExportList(aqglRiskQuarterApproveDto dto) throws IllegalAccessException {      
        List<AqglRiskQuarterRecognitionExportVo> quarterRecognitionExportList = aqglRiskQuarterApproveMapper.riskQuarterRecognitionExportList(dto.getRiskCycle(), companyName, projectName, riskLevelCode, isPlanConditionCheck);
        List<Map<String, Object>> exportData = new ArrayList<>();
        if (!quarterRecognitionExportList.isEmpty()) {
            List<AqglQuarterApproveExcelHeader> exportFiledList = dto.getExportFiled();
            try {
                for (AqglRiskQuarterRecognitionExportVo quarterRecognitionExportVo : quarterRecognitionExportList) {
                	//此处根据反射去匹配查询出的所有字段跟前端传进来的字段
                    Class<?> voClass = quarterRecognitionExportVo.getClass();
                    Map<String, Object> row = new HashMap<>();
                    for (AqglQuarterApproveExcelHeader header : exportFiledList) {
                        Field field = voClass.getDeclaredField(header.getFieldName());
                        field.setAccessible(true);
                       // String fieldValue = field.get(quarterRecognitionExportVo).toString();
                        row.put(header.getHeadName(), field.get(quarterRecognitionExportVo));
                    }
                    exportData.add(row);
                }
            } catch (NoSuchFieldException e) {
                throw new BusinessException("未匹配到导出字段:" + e.getMessage());
            }
        }else {
            throw new BusinessException("未获取到需要导出的数据!");
        }
        return exportData;
    }
  • 导出工具类(Workbook)
public static void dynamicsExportExcel(String fileName, List<String> headers, List<Map<String, Object>> data,HttpServletResponse response) throws IOException {
        Workbook workbook = new XSSFWorkbook(); // 创建工作簿
        Sheet sheet = workbook.createSheet("Sheet1"); // 创建工作表

        // sheet样式
        CellStyle sheetStyle = workbook.createCellStyle();
        sheetStyle.setBorderTop(BorderStyle.THIN); // 顶部边框
        sheetStyle.setBorderBottom(BorderStyle.THIN); // 底部边框
        sheetStyle.setBorderLeft(BorderStyle.THIN); // 左边边框
        sheetStyle.setBorderRight(BorderStyle.THIN); // 右边边框
        sheetStyle.setWrapText(true);  //设置自动换行
        sheetStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
        sheetStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        // 创建表头
        Row headerRow = sheet.createRow(0);
        headerRow.setHeight((short) 1000);
        //表头样式
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setBorderTop(BorderStyle.THIN); // 顶部边框
        headerStyle.setBorderBottom(BorderStyle.THIN); // 底部边框
        headerStyle.setBorderLeft(BorderStyle.THIN); // 左边边框
        headerStyle.setBorderRight(BorderStyle.THIN); // 右边边框
        headerStyle.setWrapText(true);  //设置自动换行
        headerStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        //设置字体
        XSSFFont font = (XSSFFont) workbook.createFont();
        font.setBold(true); // 设置加粗
        headerStyle.setFont(font);


        for (int i = 0; i < headers.size(); i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers.get(i));
            cell.setCellStyle(headerStyle);

        }


        // 填充数据、设置表格样式
        for (int i = 0; i < data.size(); i++) {
            Row dataRow = sheet.createRow(i + 1);
            Map<String, Object> rowData = data.get(i);
            for (int j = 0; j < headers.size(); j++) {
                Cell cell = dataRow.createCell(j);
                cell.setCellStyle(sheetStyle);
                Object value = rowData.get(headers.get(j));
                if (value != null) {
                    cell.setCellValue(value.toString());
                }
            }
        }

        //设置列宽度
        for (int i = 0; i < headers.size(); i++) {
            sheet.setColumnWidth(i,18 * 256);
        }

        ServletOutputStream outputStream =null;
        try {
            // 写入文件
            String name = URLEncoder.encode(fileName+".xlsx", "UTF-8");
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename="+name);
            outputStream = response.getOutputStream();
            workbook.write(outputStream);

        } catch (IOException e) {
            e.printStackTrace();
            log.error("文件导出失败");
        } finally {
            try {
                workbook.close();
                log.info(fileName + "文件导出完成!");
            } catch (IOException e) {
                log.error("文件导出失败");
                e.printStackTrace();
            }
        }

    }
  • 导出的效果
    在这里插入图片描述

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

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

相关文章

“游戏人”也能拿诺贝尔奖!

“游戏人”也能拿诺贝尔奖&#xff01; 点击蓝链领取游戏开发教程 2024年度的诺贝尔奖&#xff0c;堪称AI深刻影响传统科学领域的一次生动展现。在这一年里&#xff0c;备受瞩目的诺贝尔物理学奖与诺贝尔化学奖两大核心奖项&#xff0c;均颁给了在AI领域做出杰出贡献的研究者…

OmniGen: Unified Image Generation(代码的复现)

文章目录 论文简介模型的部署需要下载的预训练权重 模型的生成效果图像编辑的效果风格迁移的效果 总结 论文简介 OmniGen的github项目地址 OmniGen: Unified Image Generation。OmniGen 在各种图像生成任务中都表现出了卓越的性能&#xff0c;并可能大大超过现有扩散模型的极…

docker-compose安装rabbitmq 并开启延迟队列和管理面板插件(rabbitmq_delayed_message_exchange)

问题&#xff1a; 解决rabbitmq-plugins enable rabbitmq_delayed_message_exchange &#xff1a;plugins_not_found 我是在docker-compose环境部署的 services:rabbitmq:image: rabbitmq:4.0-managementrestart: alwayscontainer_name: rabbitmqports:- 5672:5672- 15672:156…

Pandas 数据可视化指南:从散点图到面积图的全面展示

Pandas 数据可视化指南&#xff1a;从散点图到面积图的全面展示 本文介绍了使用 Pandas 进行数据可视化的多种方法&#xff0c;包括散点图、折线图、条形图、直方图、饼图和面积图等&#xff0c;涵盖了常见的图表类型及其实现方式。通过提供详细的代码示例&#xff0c;展示了如…

电力电子论文(TPE、TTE)投稿经验分享

本节博客不进行技术分享&#xff0c;仅分享我的投稿经验&#xff0c;主要介绍投稿时间戳、投稿注意事项。 TPE&#xff1a; 首先介绍的是电力电子老牌顶刊——IEEE Transactions on Power Electronics&#xff0c;缩写PE、TPE、TPEL。截止写稿时间&#xff0c;该期刊Impact Fa…

YOLOv11模型架构以及使用命令介绍

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

【高等数学】1函数极限连续

1. 函数 复合函数的性质及其图形 反函数的性质及其图形 分段函数的性质及其图形 隐函数的性质及其图形 基本初等函数(通常包括幂函数、指数函数、对数函数、三角函数、反三角函数)的性质及其图形 初等函数(由基本初等函数经过有限次的四则运算和复合运算所得到的函数)…

评估 机器学习 回归模型 的性能和准确度

回归 是一种常用的预测模型&#xff0c;用于预测一个连续因变量和一个或多个自变量之间的关系。 那么&#xff0c;最后评估 回归模型 的性能和准确度非常重要&#xff0c;可以帮助我们判断模型是否有效并进行改进。 接下来&#xff0c;和大家分享如何评估 回归模型 的性能和准…

移植 AWTK 到 纯血鸿蒙 (HarmonyOS NEXT) 系统 (6) - 触屏事件

AWTK 作为一个GUI引擎&#xff0c;自然少不了对触屏事件的支持。这里我们先支持单点触摸&#xff0c;后续再支持多点手势。 1. 注册 XComponent 的触屏事件回调 这个在 AppNapi 的构造函数中完成&#xff1a; AppNapi::AppNapi(std::string &id) {id_ id;component_ n…

2024年大厂AI大模型面试题精选与答案解析

前言 随着AI市场&#xff0c;人工智能的爆火&#xff0c;在接下来的金九银十招聘高峰期&#xff0c;各大科技巨头和国有企业将会对AGI人才的争夺展开一场大战&#xff0c;为求职市场注入了新的活力。 为了助力求职者在面试中展现最佳状态&#xff0c;深入理解行业巨头的选拔标…

GNN 训练点击-购买 预测模型

搜集到click-buy数据集&#xff0c; 数据集分享在网盘 通过百度网盘分享的文件&#xff1a;数据集_20241031_220915 链接&#xff1a;https://pan.baidu.com/s/1qcXAO_P1h3Vrrui5qFbYLw?pwd6f3m 其中 yoochoose-buys.dat 特征含义buy_df.columns [session_id, timestamp, …

SpringMvc day1102

ok了家人们今天我们学习SpringMvc&#xff0c;之后学习SpringBoot&#xff0c;let‘s go 六.拦截器 6.1 拦截器概述 Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter &#xff0c;用于对处理器 ( 自己编写的 Controller) 进行预处理和后 处理。用户可以自…

项目管理(风险:范围、成本、时间、质量)

项目管理主要是围绕着范围、成本、时间、质量&#xff0c;每个部分都存在不同的风险。 存在潜在的风险方面&#xff0c;也有可能是法律风险、合作方带来的风险等。 减少风险&#xff1a; 提前与技术沟通方案。产品内部先讨论。每日例会&#xff1a;同步信息&#xff0c;减少…

6.0、静态路由

路由器最主要的功能就是转发数据包。路由器转发数据包时需要查找路由表&#xff08;你可以理解为地图&#xff09;&#xff0c;管理员可以直接手动配置路由表&#xff0c;这就是静态路由。 1.什么是路由&#xff1f; 在网络世界中&#xff0c;路由是指数据包在网络中的传输路…

网络层3——IP数据报转发的过程

目录 一、基于终点的转发 1、理解 2、IP数据报转发过程 二、最长前缀匹配 1、理解 2、主机路由 3、默认路由 三、二叉线索查找 一、基于终点的转发 1、理解 理解什么叫终点转发 IP数据报的传递&#xff0c;交给路由器后 可不可以做到直接发送给目的主机呢&#xff1f;…

VMware虚拟机Debian扩展磁盘

一、 版本 VMware&#xff1a;Workstation 17 Pro虚拟机&#xff1a;Debian11 二、 VMware虚拟机扩展 虚拟机关机状态快照或者备份&#xff1a;以免扩容失败导致文件丢失虚拟机——设置——硬盘——磁盘使用工具——扩展——扩展磁盘容量——设置为想要的大小 三、 虚拟机…

新能源汽车的未来:车载电源与V2G技术的前景

近年来&#xff0c;新能源汽车在全球市场上发展迅速&#xff0c;尤其是在中国&#xff0c;新能源汽车的月销量已经超过了燃油车。随着新能源技术的不断发展&#xff0c;新能源汽车不仅仅是作为出行工具&#xff0c;而逐渐成为“移动能源站”。本文将探讨电动汽车的车载外放电功…

JavaScript知识点梳理及案例实践

1. Date对象 创建Date对象 //方法1&#xff1a;不指定参数 var nowd1new Date(); console.log(nowd1.toLocaleString( )); //方法2&#xff1a;参数为日期字符串 var d2new Date("2004/3/20 11:12"); console.log(d2.toLocaleString( )); var d3new Date("04/…

[vulnhub]DC:7

https://www.vulnhub.com/entry/dc-7,356/ 端口扫描主机发现 探测存活主机&#xff0c;178是靶机 nmap -sP 192.168.75.0/24 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-03 13:30 CST Nmap scan report for 192.168.75.1 Host is up (0.00037s l…

探索React源码:React Diff

本篇文章我们来了解一下Diff算法的实现过程。 相关概念 React中的各种节点 假设当前存在一个DOM节点&#xff0c;触发了一次更新&#xff0c;那么在协调的过程中&#xff0c;会有四种节点和该节点相关联&#xff1a; 该DOM节点本身。 workInProgress fiber&#xff0c;更新过程…