.NET6使用MiniExcel根据数据源横向导出头部标题及数据

.NET6+MiniExcel根据数据源横向导出头部标题

MiniExcel简单、高效避免OOM的.NET处理Excel查、写、填充数据工具。

特点:
低内存耗用,避免OOM、频繁 Full GC 情况
支持即时操作每行数据
兼具搭配 LINQ 延迟查询特性,能办到低消耗、快速分页等复杂查询
轻量,不需要安装 Microsoft Office、COM+,DLL小于150KB
简便操作的 API 风格

github地址: MiniExcel
gitee地址: MiniExcel

本案例实现的功能是使用Miniexcel横向导出指标编码、指标名称,医院类型及指标对应的数据值,
要求导出效果如下所示:

  1. 第一列展示医院
  2. 头部两行动态展示指标编码、指标名称,下面展示每家医院所对应指标的值
    在这里插入图片描述
  3. 安装NuGet程序包SqlSugarCore、MiniExcel、Furion

代码如下:
结合实际情况,可以适当改下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MiniExcelLibs;
using MiniExcelLibs.Attributes;
using MiniExcelLibs.OpenXml;
using SqlSugar;namespace DJPSMS.Application.Service
{[AllowAnonymous]public class MiniexcelTest : IDynamicApiController{private readonly ISqlSugarClient _db;private readonly SqlSugarRepository<TDU_HOSPITALTEST> _tduHospitalRepository;/// <summary>/// 构造函数注入SqlSugar/// </summary>/// <param name="db"></param>public MiniexcelTest(ISqlSugarClient db, SqlSugarRepository<TDU_HOSPITALTEST> tduHospitalRepository){_db = db;_tduHospitalRepository = tduHospitalRepository;}/// <summary>/// Miniexcel导出/// </summary>/// <param name="Chapter">章节(案例中未使用)</param>/// <returns></returns>[HttpGet("DownLoadExcel")]public void DownLoadExcel([FromQuery][Required] string Chapter = "1"){try{// 导出数据源总集合var quotaAssemble = new List<Dictionary<string, object>>();// 构建横向指标标题var quotaPairy = new Dictionary<string, object>();#region 构造excel模板及数据源Log.Information($"构造excel横向指标标题开始--------");// 使用SqlSugar查询数据库// var quotaArray = _db.Queryable<DW_QUOTATEST>()//    .Where(x => x.Q_CODE.StartsWith(Chapter))//    .GroupBy(x => new { x.Q_CODE, x.Q_NAME })//    .OrderBy(x => x.Q_CODE)//    .Select(g => new { g.Q_CODE, g.Q_NAME })//    .ToList();// 所有的指标类型var quotaArray = new List<DW_QUOTATEST>(){new DW_QUOTATEST{ Q_ID = "1", Q_CODE = "1.01.01",Q_NAME ="指标1"},new DW_QUOTATEST{ Q_ID = "2", Q_CODE = "1.01.02",Q_NAME ="指标2"},new DW_QUOTATEST{ Q_ID = "3", Q_CODE = "1.01.03",Q_NAME ="指标3"},new DW_QUOTATEST{ Q_ID = "4", Q_CODE = "1.01.04",Q_NAME ="指标4"},new DW_QUOTATEST{ Q_ID = "5", Q_CODE = "1.01.05",Q_NAME ="指标5"},new DW_QUOTATEST{ Q_ID = "6", Q_CODE = "1.01.06",Q_NAME ="指标6"},new DW_QUOTATEST{ Q_ID = "7", Q_CODE = "1.01.07",Q_NAME ="指标7"},new DW_QUOTATEST{ Q_ID = "8", Q_CODE = "1.01.08",Q_NAME ="指标8"},new DW_QUOTATEST{ Q_ID = "9", Q_CODE = "1.01.09",Q_NAME ="指标9"},new DW_QUOTATEST{ Q_ID = "10", Q_CODE = "1.01.10",Q_NAME ="指标10"},new DW_QUOTATEST{ Q_ID = "11", Q_CODE = "1.01.11",Q_NAME ="指标11"},new DW_QUOTATEST{ Q_ID = "12", Q_CODE = "1.01.12",Q_NAME ="指标12"},new DW_QUOTATEST{ Q_ID = "13", Q_CODE = "1.01.13",Q_NAME ="指标13"}};// 設置列宽var config = new OpenXmlConfiguration{DynamicColumns = CreateDynamicColumns(quotaArray.GroupBy(x => x.Q_CODE).Select(x => x.Key).ToList())};// 构建横向指标标题quotaPairy["医院名称"] = "";for (int i = 0; i < quotaArray.Count; i++){if (quotaPairy.ContainsKey(quotaArray[i].Q_CODE)) continue;var propertyCode = quotaArray[i].Q_CODE;var propertyName = quotaArray[i].Q_NAME;quotaPairy[propertyCode] = propertyName;}quotaAssemble.Add(quotaPairy);Log.Information($"构造excel横向指标标题结束--------");// 构建第一列医院类型var hospitalList = new List<TDU_HOSPITALTEST>(){new TDU_HOSPITALTEST{ FJGDM ="1",FDESC ="测试医院1" },new TDU_HOSPITALTEST{ FJGDM ="2",FDESC ="测试医院2" },new TDU_HOSPITALTEST{ FJGDM ="3",FDESC ="南京第一" },new TDU_HOSPITALTEST{ FJGDM ="3",FDESC ="测试医院4" },new TDU_HOSPITALTEST{ FJGDM ="4",FDESC ="测试医院5" },new TDU_HOSPITALTEST{ FJGDM ="5",FDESC ="测试医院6" },new TDU_HOSPITALTEST{ FJGDM ="6",FDESC ="测试医院7" },new TDU_HOSPITALTEST{ FJGDM ="7",FDESC ="测试医院8" },new TDU_HOSPITALTEST{ FJGDM ="8",FDESC ="测试医院9" },new TDU_HOSPITALTEST{ FJGDM ="9",FDESC ="测试医院10" },new TDU_HOSPITALTEST{ FJGDM ="10",FDESC ="测试医院11" },new TDU_HOSPITALTEST{ FJGDM ="11",FDESC ="测试医院12" },};//每家医院对应的指标的值var quotaValuePairy = new Dictionary<string, object>();// 总数据源,一般来说是从数据库联表中查询的数据,这边是声明的测试数据List<HospitalViewCodeDetailTest> resultList = new List<HospitalViewCodeDetailTest>(){// 测试医院1的数据new HospitalViewCodeDetailTest { Code = "1.01.01", CodeName = "指标1",HospitalCode ="1",HospitalName ="测试医院1" ,QValue = "11.8"},new HospitalViewCodeDetailTest { Code = "1.01.02", CodeName = "指标2",HospitalCode ="1",HospitalName ="测试医院2" ,QValue = "12.8"},// 测试医院2的数据new HospitalViewCodeDetailTest { Code = "1.01.01", CodeName = "指标1",HospitalCode ="2",HospitalName ="测试医院1" ,QValue = "22.6"},new HospitalViewCodeDetailTest { Code = "1.01.02", CodeName = "指标2",HospitalCode ="2",HospitalName ="测试医院1" ,QValue = "23.2"} ,// 测试医院3的数据new HospitalViewCodeDetailTest { Code = "1.01.01", CodeName = "指标1",HospitalCode ="3",HospitalName ="测试医院3" ,QValue = "65.8"} ,new HospitalViewCodeDetailTest { Code = "1.01.02", CodeName = "指标2",HospitalCode ="3",HospitalName ="测试医院4" ,QValue = "25.1"}};// 填充对应的指标值for (int i = 0; i < hospitalList.Count; i++){quotaValuePairy = new Dictionary<string, object>(); // 在每次迭代中创建新的字典对象var hospitalCodeDetails = resultList.Where(x => x.HospitalCode == hospitalList[i].FJGDM).Select(x => new{x.Code,x.QValue}).ToList();quotaValuePairy["医院名称"] = hospitalList[i].FDESC;for (int o = 0; o < quotaArray.Count; o++){if (quotaValuePairy.ContainsKey(quotaArray[o].Q_CODE)) continue;quotaValuePairy[quotaArray[o].Q_CODE] = hospitalCodeDetails.FirstOrDefault(x => x.Code == quotaArray[o].Q_CODE)?.QValue; //指标值}quotaAssemble.Add(quotaValuePairy);}#endregion#region 导出excelif (quotaAssemble.Count > 0){Log.Information("正在导出......");// 读取json文件中的自定义保存路径// App.GetConfig官网介绍地址:http://furion.baiqian.ltd/docs/global/app?_highlight=getconfig#12-%E8%8E%B7%E5%8F%96%E9%85%8D%E7%BD%AE%E5%AF%B9%E8%B1%A1//可以改成自己地址string savePath = $"{App.GetConfig<string>("GenerateExcelOfHospitalFillingJobConfig:SavePath")}\\DownLoadExcel\\";if (!Directory.Exists(savePath)){Directory.CreateDirectory(savePath);}string filename = $"{DateTime.Now:yyyyMMddHHmmss}.xlsx";var absoluteFilePath = Path.Combine(savePath, filename);// 保存MiniExcel.SaveAs(absoluteFilePath, quotaAssemble.ToArray(),configuration: config);Log.Information($"{filename}导出成功!");}#endregion}catch (Exception ex){// 异常处理逻辑Log.Error($"发生异常: {ex.Message}");}}/// <summary>/// 设置行宽/// </summary>/// <returns></returns>private DynamicExcelColumn[] CreateDynamicColumns(List<string> dwQuota){var dynamicColumns = new List<DynamicExcelColumn>{new DynamicExcelColumn("医院名称") { Index = 0, Width = 30 }};dynamicColumns.AddRange(dwQuota.Select((codeTitle, codeIndex) =>{if (string.IsNullOrEmpty(codeTitle)){// 处理空值的情况,例如使用默认列名或跳过该列return null; // 返回 null 或者其他处理方式}else{return new DynamicExcelColumn(codeTitle) { Index = codeIndex + 1, Width = 25 };}}).Where(c => c != null).ToArray());return dynamicColumns.ToArray();}}/// <summary>/// 指标实体/// </summary>public class DW_QUOTATEST{/// <summary>/// 主键guid/// </summary>[SugarColumn(ColumnDescription = "主键id", Length = 32, IsPrimaryKey = true)]public string Q_ID { get; set; }/// <summary>/// 编码/// </summary>public string Q_CODE { get; set; }/// <summary>/// 指标名称/// </summary>public string Q_NAME { get; set; }}/// <summary>/// 医院实体/// </summary>public class TDU_HOSPITALTEST{public string FJGDM { get; set; }public string FSEQ { get; set; }public string FDESC { get; set; }}public class HospitalViewCodeDetailTest{/// <summary>/// 医院编码/// </summary>public string HospitalCode { get; set; }/// <summary>/// 医院名称/// </summary>public string HospitalName { get; set; }/// <summary>/// 指标编码/// </summary>public string Code { get; set; }/// <summary>/// 指标名称/// </summary>public string CodeName { get; set; }/// <summary>/// QValue指标值/// </summary>public string QValue { get; set; }}
}

最后效果图如下所示:
在这里插入图片描述
写的不好,如有错误还请指正

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux中安装部署环境(JAVA)

目录 在Linux中安装jdk 包管理器yum安装jdk JDK安装过程中的问题 验证安装jdk 在Linux中安装tomcat 安装mysql 在Linux中安装jdk jdk在Linux中的安装方式有很多种, 这里介绍最简单的方法, 也就是包管理器方法: 包管理器yum安装jdk Linux中常见的包管理器有: yumaptp…

论文阅读:Auto White-Balance Correction for Mixed-Illuminant Scenes

论文阅读&#xff1a;Auto White-Balance Correction for Mixed-Illuminant Scenes 今天介绍一篇混合光照下的自动白平衡的文章 Abstract 自动白平衡&#xff08;AWB&#xff09;是相机 ISP 通路中比较重要的一个模块&#xff0c;主要用于校正环境光照引起的色偏问题&#x…

计算机视觉的应用17-利用CrowdCountNet模型解决人群数量计算问题(pytorch搭建模型)

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用17-利用CrowdCountNet模型解决人群数量计算问题(pytorch搭建模型)。本篇文章&#xff0c;我将向大家展示如何使用CrowdCountNet这个神奇的工具&#xff0c;以及它是如何利用深度学习技术来解决复杂…

【设计一个缓存--针对各种类型的缓存】

设计一个缓存--针对各种类型的缓存 1. 设计顶层接口2. 设计抽象类 -- AbstractCacheManager3. 具体子类3.1 -- AlertRuleItemExpCacheManager3.2 -- AlertRuleItemSrcCacheManager 4. 类图关系 1. 设计顶层接口 // 定义为一个泛型接口,提供给抽象类使用 public interface Cach…

数据资产入表,给企业带来的机遇和挑战

作为推动数字经济发展的核心要素&#xff0c;近年来&#xff0c;数据资源对于企业特别是相关数据企业的价值和作用正日益凸显。 数据资产入表之后&#xff0c;能够为企业经营带来实质性的收益。“随着数据资产的纳入&#xff0c;企业的资产也出现了新标的。在资产负债表中&…

【2023春李宏毅机器学习】快速了解机器学习基本原理

文章目录 机器学习约等于机器自动找一个函数 机器学习分类 regression&#xff1a;输出为连续值classification&#xff1a;输出为一个类别structured learning&#xff1a;又叫生成式学习generative learning 生成有结构的物件&#xff08;如&#xff1a;影像、句子&#xf…

ajax异步传值以及后端接收参数的几种方式

异步传值 第一种呢&#xff0c;也是最简单的一种&#xff0c;通过get提交方式&#xff0c;将参数在链接中以问号的形式进行传递 // 前台传值方法 // 触发该方法调用ajaxfunction testAjax(yourData) {$.ajax({type: "get", // 以get方式发起请求url: "/yo…

IC卡操作软件支持PN532

IC卡操作软件&#xff0c;在知道卡片密码的情况下&#xff0c;可以对卡片修改数据&#xff0c;格式化清卡&#xff0c;修改UID卡和CUID卡的卡号&#xff0c;锁UFUID卡等 卡片dump文件拖进软件&#xff0c;即可打开文件&#xff0c;编辑修改文件&#xff0c;写卡&#xff0c;就…

upload-labs关卡11(双写后缀名绕过)通关思路

文章目录 前言一、回顾前几关知识点二、靶场第十一关通关思路1、看源代码2、bp抓包双写后缀名绕过3、检查文件是否成功上传 总结 前言 此文章只用于学习和反思巩固文件上传漏洞知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练习的平台&#xff0c;不能随意去尚未授权的…

将Agent技术的灵活性引入RPA,清华等发布自动化智能体ProAgent

近日&#xff0c;来自清华大学的研究人员联合面壁智能、中国人民大学、MIT、CMU 等机构共同发布了新一代流程自动化范式 “智能体流程自动化” Agentic Process Automation&#xff08;APA&#xff09;&#xff0c;结合大模型智能体帮助人类进行工作流构建&#xff0c;并让智能…

Neo4j数据库介绍及简单使用

图数据库介绍 图数据库是一种专门设计用于存储和管理图形数据的数据库类型。在图数据库中&#xff0c;数据以图的形式表示&#xff0c;其中节点表示实体&#xff0c;边表示实体之间的关系。这种表示方式非常适合处理具有复杂关系的数据&#xff0c;如社交网络、推荐系统、网络…

代码随想录算法训练营第五十九天丨 单调栈02

503.下一个更大元素II 思路 做本题之前建议先做739. 每日温度 (opens new window)和 496.下一个更大元素 I (opens new window)。 这道题和739. 每日温度 (opens new window)也几乎如出一辙。 不过&#xff0c;本题要循环数组了。 关于单调栈的讲解我在题解739. 每日温度 …

数据结构 栈与队列详解!!

一.栈 关于内存中的栈和数据结构中的栈是不同的&#xff0c;本章着重讲的是数据结构的栈。 这是一张关于栈的表达图。从图中可以看出栈很像是一副卡牌&#xff0c;发牌时只能从上取出&#xff0c;即出栈。 而入栈则是像你出牌后&#xff0c;要把你出的牌压在上一张出的牌上面。…

asp.net校园二手交易平台系统VS开发sqlserver数据库web结构c#编程计算机网页

一、源码特点 asp.net校园二手交易平台系统 是一套完善的web设计管理系统&#xff0c;系统采用mvc模式&#xff08;BLLDALENTITY&#xff09;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 vs2010&#xff0c;数据库为sqlserver2008&a…

pytorch单精度、半精度、混合精度、单卡、多卡(DP / DDP)、FSDP、DeepSpeed模型训练

pytorch单精度、半精度、混合精度、单卡、多卡&#xff08;DP / DDP&#xff09;、FSDP、DeepSpeed&#xff08;环境没搞起来&#xff09;模型训练代码&#xff0c;并对比不同方法的训练速度以及GPU内存的使用 代码&#xff1a;pytorch_model_train FairScale&#xff08;你真…

[工业自动化-22]:西门子S7-15xxx编程 - 软件编程 - 如何PLC建立用户界面: SIMATIC 面板式HMI 或工控机PC HMI

目录 前言&#xff1a; 一、PLC&#xff08;可编程逻辑控制器&#xff09;的用户界面支持方式 1.1 概述 1.2 西门子&#xff08;Siemens&#xff09;的人机界面&#xff08;HMI&#xff09;支持多种类型 1.3 PC HMI VS SIMATIC HMI 二、PC—HMI—PLC连接架构的实现 三、…

Go——一、Go语言安装及介绍

Go 一、Windows下安装Go1、下载Go2、配置环境变量3、下载Jetbrain下的GoLang4、编写hello world5、编译和执行 二、Go语言介绍1、开发文档2、Go语言核心开发团队3、为什么要创建Go4、Go语言发展史5、Go语言特点6、Golang执行过程6.1 执行过程分析6.2 编译是什么 7、开发注意事项…

WinForms C# 导入和导出 CSV 文件 Spread.NET

使用 WinForms C# 和 VB.NET 导入和导出 CSV 文件 2023 年 11 月 17 日 使用 Spread.NET 直接在 .NET WinForms 应用程序中处理 CSV 文件。 Spread.NET可帮助您创建电子表格、网格、仪表板和表单。它包括一个强大的计算引擎&#xff0c;具有 450 多个函数以及导入和导出 Micros…

【OpenCV】仿射变换中cv2.estimateAffine2D 的原理

目录 一、介绍 二、仿射变换矩阵 (M) 1.M中六个元素的说明 2.计算旋转角度 3.M的计算过程 三、输出状态 (inliers) 四、错切参数 一、介绍 cv2.estimateAffine2D 是 OpenCV 库中的一个函数&#xff0c;用于估计两个二维点集之间的仿射变换矩阵。即第一个点集经仿射变换转…

解决Requests中使用httpbin服务器问题:自定义URL的实现与验证

问题背景 在使用Python的Requests模块进行单元测试时&#xff0c;可能会遇到无法使用本地运行的httpbin服务器进行测试的问题。这是因为测试脚本允许通过环境变量HTTPBIN_URL指定用于测试的本地httpbin实例&#xff0c;但在某些测试用例中&#xff0c;URL是硬编码为httpbin.or…