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

news2024/10/6 10:35:01

为了方便代码编写和测试,把很多代码都放在一个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);
                }
                #endregion

                var 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测试效果如下:

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

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

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

相关文章

sql中如何添加数据?

添加 在 SQL 中添加数据通常使用INSERT语句。INSERT语句用于将新的数据行插入到数据库表中。 基本的INSERT语句语法如下&#xff1a; INSERT INTO table_name (column1, column2,...) VALUES (value1, value2,...);其中&#xff1a; INSERT INTO&#xff1a;指定要插入数据…

探索设计模式的魅力:AI大模型如何赋能C/S模式,开创服务新纪元

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 AI大模型如何赋能C/S模式&#xff0c;开创服务新纪元 数字化飞速发展的时代&#xff0c;AI大模型…

从第三方数据集成工具迁移到Apache SeaTunnel的实操经验分享

在如今这个数据至上的商业环境中&#xff0c;构建一个高效、可靠的数据仓库对企业来说不仅是一项基础性工作&#xff0c;更是推动业务洞察、决策支持和创新的关键&#xff0c;而数据集成技术在此发挥着至关重要的作用&#xff0c;其时效性和准确性直接影响着下游业务的效率和产…

连接Redis不支持集群错误,ERR This instance has cluster support disabled,解决方案

1. 问题背景 调整redis的配置后&#xff0c;启动程序时&#xff0c; 会报如下错误&#xff1a; [redis://172.16.0.8xxx]: ERR This instance has cluster support disabledSuppressed: io.lettuce.core.RedisCommandExecutionException: ERR This instance has cluster supp…

电商技术揭秘四:电商平台的物流管理系统

文章目录 引言一、物流管理系统的功能与架构1.1 物流管理系统在电商平台中的作用概述保障订单的及时配送优化库存管理控制运营成本提升客户服务水平支持数据驱动的决策应对市场变化 1.2 订单处理功能分析自动化处理流程订单分配与履行错误检测与处理机制实时订单状态更新订单数…

群晖配置FTP服务结合内网穿透实现公网访问本地NAS中储存文件

文章目录 1. 群晖安装Cpolar2. 创建FTP公网地址3. 开启群晖FTP服务4. 群晖FTP远程连接5. 固定FTP公网地址6. 固定FTP地址连接 本文主要介绍如何在群晖NAS中开启FTP服务并结合cpolar内网穿透工具&#xff0c;实现使用固定公网地址远程访问群晖FTP服务实现文件上传下载。 Cpolar内…

微信小程序开发学习笔记——4.7 api中navigate路由接口与组件的关系

>>跟着b站up主“咸虾米_”学习微信小程序开发中&#xff0c;把学习记录存到这方便后续查找。 一、跳转 1、方法一&#xff1a;组件 组件-导航-navigator <navigator url"/pages/demo/demo?id123" open-type"reLaunch">go demo page <…

windows搭建ftp实现局域网共享文件

一、开启ftp服务 1.使用 win Q 键&#xff0c;快捷打开搜索框 2.搜索框内搜索 “控制面板” 3. 进入控制面板内选择 ”程序“ 4. 单击进入 “启用或关闭windows功能” 5. 找到并展开“internet information services”、 6. 建议展开后全选 “FTP服务器” 和 “web管理工…

Mysql的MHA高可用集群部署及故障切换

目录 一、MHA概念 1、MHA的组成 2、MHA的特点 二、搭建MysqlMHA 1、实验思路 1.1 MHA架构 1.2 故障模拟 2、实验环境、安装包 3、服务搭建 3.1 所有服务器&#xff0c;关闭系统防火墙和安全机制 3.2 修改master &#xff08;192.168.170.111&#xff09;、slave1&am…

ATFX汇市:美国3月ISM制造业PMI为50.3,远高于前值47.8,经济景气度高

ATFX汇市&#xff1a;虽然国际市场的主流预期是美联储将于今年六月份开启首次降息&#xff0c;但降息的前提条件——美国经济显著衰退——似乎远未到来。此前公布的美国非农就业报告显示&#xff0c;新增非农就业人口27.5万人&#xff0c;处于近12个月的数据峰值水平&#xff1…

Modbus转Profinet网关解决主从设备间通信数据丢失难题

在接到现场关于Modbus转Profinet网关&#xff08;XD-MDPN100&#xff09;配置时出现信不稳定或数据丢失的问题的反馈后。对于现场反馈的Modbus转Profinet网关配置问题&#xff0c;特出专项答疑。 解决Modbus转Profinet网关&#xff08;XD-MDPN100&#xff09;通信不稳定或数据丢…

ddres( ) 组站星双差方程和设计矩阵

1 ddres( )参数介绍 rtklib中进行的单频解算 双差观测值&#xff0c;单差的模糊度 单频点双差 DD (double-differenced) phase/code residuals ------------------------------ x 模糊度 P 方差-协方差阵 sat 共识卫星列表 ns 共识卫星数量 y…

CLIP 图文检索,相似度计算

CLIP 是OpenAI提出的神经网络&#xff0c;它可以从自然语言监督中有效地学习视觉概念。 CLIP 可以应用于任何视觉分类基准&#xff0c;只需提供要识别的视觉类别的名称&#xff0c;类似于 GPT-2 和 GPT-3 的“零样本”功能。 相关paper 用法可以参考github 这里举几个使用CLI…

context switch的切换过程(TTBR0的切换/ASID的介绍)

快速链接: 【精选】ARMv8/ARMv9架构入门到精通-[目录] &#x1f448;&#x1f448;&#x1f448; context switch的切换 操作系统中可能存在多个任务&#xff0c; 内核调度器周期性地将执行从一项任务转移到另一项任务。在这个过程中&#xff0c;操作系统会保存上一个进程的执…

ISELED-演示项目代码

目录 一、main函数二、点灯函数 一、main函数 int main(void) {/* Write your local variable definition here */iseledInitType.crcEnable 1;iseledInitType.firstLedAdr 1;iseledInitType.tempCmpEnable 0;iseledInitType.voltSwing 0;/*** End of Processor Expert in…

windows下通过vscode访问ubuntu(绝大部分Linux下开发所采用的方案)

前言 本篇博客是介绍VSCode远程连接Ubuntu进行开发的解决方案&#xff0c;前提是安装好了VMWare&#xff0c;Ubuntu&#xff0c;windows下的VSCode。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关…

大模型prompt技巧——思维链(Chain-of-Thought)

1、Zero-shot、One-shot、Few-shot 与fintune prompt的时候给出例子答案&#xff0c;然后再让模型回答。 2、zero-shot-CoT “Let’s think step by step”有奇迹效果 3、多数投票提高CoT性能——自洽性&#xff08;Self-consistency&#xff09; 多个思维链&#xff0c;然后取…

使用Thymeleaf配置国际化页面

在国际化&#xff08;i18n&#xff0c;即 Internationalization 的缩写&#xff0c;其中“i”和“n”之间有18个字母&#xff09;的上下文中&#xff0c;Thymeleaf 和 Spring Boot 可以很容易地一起工作&#xff0c;以支持多种语言的页面显示。下面是如何在 Spring Boot 应用中…

干货教程【AI篇】| AI大模型文字生成视频环境部署小白级教程

只需要一个主题、一个词语&#xff0c;或者一段描述&#xff0c;就可以生成一个完整的短视频的工具来啦&#xff01; 在文章下方公众号中回复关键词【aivd】即可获取完整代码和配套软件 工具获取 ps&#xff1a;本文不涉及任何代码开发工作&#xff0c;仅仅作为软件推荐。 如…

实验:基于Red Hat Enterprise Linux系统的创建磁盘和磁盘分区(二、三)

目录 一. 实验目的 二. 实验内容 三. 实验设计描述及实验结果 实验二&#xff1a; 1. 为nvme0n2p1设备建立配额属性和文件(EXT) 2. 要求自己名字的用户只能存储不超过200M的文件&#xff0c;总数量不能大于10个 quotacheck [选项] 文件系统 edquota quotaon [选项] 文件系…