当前位置: 首页 > news >正文

基于MiniExcel的三种常用导出Excel方法(固定列导出、动态列导出、按模板导出)

为了方便代码编写和测试,把很多代码都放在一个class里面,实际开发根据需要放到对应的目录下即可。

1.使用nuget下载安装miniexcel;

2.编写对应的测试接口,具体代码如下:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;
using AutoMapper;
using MiniExcelLibs.Attributes;
using MiniExcelLibs;
using MiniExcelLibs.OpenXml;
using System.Linq;namespace YY.Webapi.Controllers
{/// <summary>/// miniexcel测试/// </summary>[Route("api/[controller]")][ApiController][Produces("application/json")][AllowAnonymous]public class MiniExcelController : ControllerBase{private readonly IMapper _mapper;public MiniExcelController(IMapper mapper){_mapper = mapper;}/// <summary>/// 固定列导出/// </summary>/// <param name="input"></param>/// <returns></returns>/// <exception cref="Exception"></exception>[HttpPost("Export")]public async Task<IActionResult> Export(){try{var models = new Custome().GetProducts();var exportDtos = _mapper.Map<List<CustomeExportDto>>(models);var memoryStream = new MemoryStream();memoryStream.SaveAs(exportDtos);memoryStream.Seek(0, SeekOrigin.Begin);return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"){FileDownloadName = $"固定列报表导出-{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"};}catch (Exception ex){throw new Exception($"固定列报表导出出现错误:{ex.Message}");}}/// <summary>/// 动态列导出(指定列导出)/// </summary>/// <param name="columnParams"></param>/// <returns></returns>/// <exception cref="Exception"></exception>[HttpPost("ExportByAssignColumn")][AllowAnonymous]public async Task<IActionResult> ExportByAssignColumn(List<CustomeParam> columnParams){try{if (columnParams == null || !columnParams.Any()) throw new Exception("请选择需要导出的列!");var dtos = new Custome().GetProducts();#region 配置var config = new OpenXmlConfiguration { };List<DynamicExcelColumn> objs = new List<DynamicExcelColumn>();int index = 0;foreach (var columnParam in columnParams){objs.Add(new DynamicExcelColumn(columnParam.ColumnDisplayName) { Index = index++, Width = columnParam.ColumnWidth });}config.DynamicColumns = objs.ToArray();#endregion#region 获取值var values = new List<Dictionary<string, object>>();foreach (var dto in dtos){var dic = new Dictionary<string, object>();foreach (var columnParam in columnParams){dic.Add(columnParam.ColumnDisplayName, GetModelValue(columnParam.ColumnName, dto));}values.Add(dic);}#endregionvar memoryStream = new MemoryStream();memoryStream.SaveAs(values, configuration: config);memoryStream.Seek(0, SeekOrigin.Begin);return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"){FileDownloadName = $"动态列报表导出-{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"};}catch (Exception ex){throw new Exception($"动态列报表导出错误:{ex.Message}");}}/// <summary>/// 按模板导出/// </summary>/// <param name="id"></param>/// <returns></returns>/// <exception cref="Exception"></exception>[HttpPost("{id}/ExportByTemplate")]public async Task<IActionResult> ExportByTemplate([FromRoute] int id){try{var entity = new Custome() { Id = 1, Code = "Code", Name = "Test", Price = 12, CreateTime = DateTime.Now };string templatePath = $@"C:\Users\Administrator\Desktop\报表模板.xlsx";var value = new{Code = entity.Code,Name = entity.Name};byte[] bytes = System.IO.File.ReadAllBytes(templatePath);var memoryStream = new MemoryStream();await memoryStream.SaveAsByTemplateAsync(bytes, value);memoryStream.Seek(0, SeekOrigin.Begin);return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"){FileDownloadName = $"按模板报表导出-{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"};}catch (Exception ex){throw new Exception($"按模板报表导出错误:{ex.Message}");}}#region 私有方法/// <summary>/// 根据字段名获取对应的值/// </summary>/// <param name="fieldName"></param>/// <param name="obj"></param>/// <returns></returns>private string GetModelValue(string fieldName, object obj){try{object o = obj.GetType().GetProperty(fieldName).GetValue(obj, null);string Value = Convert.ToString(o);if (string.IsNullOrEmpty(Value)) return "";return Value;}catch{return "";}}#endregion}public class Custome{/// <summary>/// 产品Id/// </summary>public int Id { get; set; }/// <summary>/// 产品编码/// </summary>public string Code { get; set; }/// <summary>/// 产品名称/// </summary>public string Name { get; set; }/// <summary>/// 价格/// </summary>public int Price { get; set; }/// <summary>/// 创建时间/// </summary>public DateTime CreateTime { get; set; }public List<Custome> GetProducts(){var products = new List<Custome>();for (int i = 0; i < 1000; i++){products.Add(new Custome{Id = i + 1,Code = $"Code-{(i + 1).ToString()}",Name = $"Name-{(i + 1).ToString()}",Price = Random.Shared.Next(10, 100),CreateTime = DateTime.Now});}return products;}}public class CustomeExportDto{/// <summary>/// 产品编码/// </summary>[ExcelColumn(Name = "产品编码", Width = 12)]public string Code { get; set; }/// <summary>/// 产品名称/// </summary>[ExcelColumn(Name = "产品名称", Width = 12)]public string Name { get; set; }/// <summary>/// 价格/// </summary>[ExcelColumn(Name = "价格", Width = 12)]public int Price { get; set; }/// <summary>/// 创建时间/// </summary>[ExcelColumn(Name = "创建时间", Width = 12, Format = "yyyy-MM-dd HH:mm:ss")]public DateTime CreateTime { get; set; }}public class CustomeParam{/// <summary>/// 列名/// </summary>public string ColumnName { get; set; }/// <summary>/// 列显示名/// </summary>public string ColumnDisplayName { get; set; }/// <summary>/// 列宽/// </summary>public double ColumnWidth { get; set; }}
}

3.固定列和按模板导出Excel都比较常规,,其中的动态列导出是根据前端传进来的参数进行选择性的动态列导出,swagger测试效果如下:

在这里插入图片描述
在这里插入图片描述
导出的文件如下:
在这里插入图片描述

相关文章:

基于MiniExcel的三种常用导出Excel方法(固定列导出、动态列导出、按模板导出)

为了方便代码编写和测试&#xff0c;把很多代码都放在一个class里面&#xff0c;实际开发根据需要放到对应的目录下即可。 1.使用nuget下载安装miniexcel&#xff1b; 2.编写对应的测试接口&#xff0c;具体代码如下: using Microsoft.AspNetCore.Authorization; using Micr…...

MATLAB科研绘图与学术图表绘制从入门到精通

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…...

C++核心高级编程 --- 1、内存分区模型 2、引用

文章目录 第一章&#xff1a;1.内存分区模型1.1 程序运行前1.2 程序运行后1.3 new操作符 第二章&#xff1a;2.引用2.1 使用2.2 注意事项2.3 做函数参数2.4 做函数返回值2.5 本质2.6 常量引用 第一章&#xff1a; 1.内存分区模型 4个区域&#xff1a; 代码区&#xff1a;存放…...

winform日历控件_进度条控件

在 Windows Forms 应用程序中使用日历控件 (如 MonthCalendar 或 DateTimePicker) 和进度条控件 (如 ProgressBar) 是一个很好的练习&#xff0c;以了解这些控件的工作方式。以下是一些基本的步骤来实践这些控件&#xff1a; 日历控件&#xff1a; 添加 MonthCalendar 控件&am…...

Java进阶-反射的详解与应用

本文深入探讨了Java反射机制的核心概念、应用实例及其在现代Java开发中的重要性。文章首先介绍了反射的基本原理和能力&#xff0c;包括在运行时动态获取类信息、操作对象字段和方法的能力。随后&#xff0c;通过具体代码示例&#xff0c;展示了如何利用反射进行字段访问、方法…...

蓝桥杯算法题——暴力枚举法

先估算这个数小于3的50次方 cnt0 for i in range(50):for j in range(50):for k in range(50):a3**ib5**jc7**kif a*b*c<59084709587505:cnt1 print(cnt-1)#当ijk都为0时&#xff0c;a*b*c1不是幸运数字所以要减去...

【教程】Kotlin语言学习笔记(六)——泛型

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【Kotlin语言学习】系列文章 第一章 《认识Kotlin》 第二章 《数据类型》 第三章 《数据容器》 第四章 《方法》 第五章 《L…...

【中文视觉语言模型+本地部署 】23.08 阿里Qwen-VL:能对图片理解、定位物体、读取文字的视觉语言模型 (推理最低12G显存+)

项目主页&#xff1a;https://github.com/QwenLM/Qwen-VL 通义前问网页在线使用——&#xff08;文本问答&#xff0c;图片理解&#xff0c;文档解析&#xff09;&#xff1a;https://tongyi.aliyun.com/qianwen/ 论文v3. : 一个全能的视觉语言模型 23.10 Qwen-VL: A Versatile…...

【Qt 学习笔记】Qt 背景介绍

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt 背景介绍 文章编号&#xff1a;Qt 学习笔记 / 01 文章目录 Qt 背景…...

C++递推算法

数塔问题 #include<bits/stdc.h> using namespace std; void f(int,int,int); int a[100][100]; int n; int main() {cin>>n;for(int i0;i<n;i){for(int j0;j<1i;j){cin>>a[i][j];}}for(int in-2;i>0;i--){for(int j0;j<i1;j){a[i][j]a[i][j]ma…...

Go项目结构整洁实现|GitHub 3.5k

一、前言 hi&#xff0c;大家好&#xff0c;这里是白泽。今天给大家分享一个GitHub &#x1f31f; 3.5k 的 Go项目&#xff1a;go-backend-clean-arch https://github.com/amitshekhariitbhu/go-backend-clean-architecture 这个项目是一位老外写的&#xff0c;通过一个 HTT…...

Python读取PDF文字 去掉页眉页脚

使用PyMuPDF&#xff08;即fitz&#xff09;读取PDF中的text时&#xff0c;会把页码也读进来。所以&#xff0c;有时候就需要让程序忽略页眉和页脚&#xff0c;或者直接删除页眉和页脚。 根据fitz的文档&#xff1a;Page - PyMuPDF 1.24.0 documentation get_text的clip参数可…...

Linux:入门篇

文章目录 前言1. Linuxd的安装环境2.Linux的简单介绍2.1 新建目录2.2 新建文件 3.指令到底是什么&#xff1f;4.shell命令以及运行原理5.总结 前言 很多人对于Linux的学习总是感觉无法下手&#xff0c;不知道从何开始学习&#xff0c;相信这篇文章将会为你提供一个清晰的思路。…...

NSSCTF Round#20 Basic 真亦假,假亦真 CSDN_To_PDF V1.2 出题笔记 (附wp+源码)

真亦假&#xff0c;假亦真 简介&#xff1a;java伪造php一句话马。实则信息泄露一扫就出&#xff0c;flag在/flag里面。 题目描述&#xff1a;开开心心签个到吧&#xff0c;祝各位师傅们好运~ 静态flag&#xff1a;NSS{Checkin_h4v3_4_g00D_tINNe!} /路由显示 <?php e…...

处理关于 React lazy 白屏的两种方案

这篇文章是今天在阅读 React 官方文档的时候看到的一个关于 处理 lazy 体验问题的小技巧&#xff0c;在这里记录一下 当我们使用 React.lazy 去懒加载一个路由组件&#xff0c;在不做任何其他处理的情况下从其他页面首次进入到这个懒加载的路由页面时&#xff0c;肯定会出现白屏…...

Nginx 基础

文章目录 Nginx概念安装下载上传安装包执行准备条件指定安装位置编译和安装启动服务创建启动脚本 linux文件目录nginx运行原理nginx配置域名概念和原理域名配置 Nginx 概念 Nginx 是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。Nginx是…...

C++完美转发(适合小白)

我们知道&#xff0c;C中有左值引用和右值引用&#xff0c;首先我们要知道什么是左值什么是右值。 左值&#xff1a;表达式结束后依然存在的持久对象。左值可以出现在赋值语句的左边或右边。例如&#xff0c;变量和函数返回的引用都是左值。左值通常有持久的地址&#xff0c;可…...

如何创建自己的 Spring Boot Starter 并为其编写单元测试

当我们想要封装一些自定义功能给别人使用的时候&#xff0c;创建Spring Boot Starter的形式是最好的实现方式。如果您还不会构建自己的Spring Boot Starter的话&#xff0c;本文将带你一起创建一个自己的Spring Boot Starter。 快速入门 创建一个新的 Maven 项目。第三方封装的…...

C++ :STL中deque的原理

deque的结构类似于哈希表&#xff0c;使用一个指针数组存储固定大小的数组首地址&#xff0c;当数据分布不均匀时将指针数组内的数据进行偏移&#xff0c;桶不够用的时候会像vector一样扩容然后将之前数组中存储的指针拷贝过来&#xff0c;从原理可以看出deque的性能是非常高的…...

AttributeError: ‘Namespace‘ object has no attribute ‘EarlyStopping‘

报错原因 这个报错信息表明在Python脚本train.py中尝试访问命令行参数args.EarlyStopping时出错&#xff0c;具体错误是AttributeError: Namespace对象没有名为EarlyStopping的属性。 在Python的argparse模块中&#xff0c;当我们通过命令行传递参数并解析时&#xff0c;解析…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

IP选择注意事项

IP选择注意事项 MTP、FTP、EFUSE、EMEMORY选择时&#xff0c;需要考虑以下参数&#xff0c;然后确定后选择IP。 容量工作电压范围温度范围擦除、烧写速度/耗时读取所有bit的时间待机功耗擦写、烧写功耗面积所需要的mask layer...