C# 实现二维数据数组导出到 Excel
目录
功能需求
范例运行环境
Excel DCOM 配置
设计实现
组件库引入
编辑
方法设计
生成二维数据数组
核心方法实现
调用示例
总结
功能需求
将数据库查询出来的数据导出并生成 Excel 文件,是项目中经常使用的一项功能。本文将介绍通过数据集生成二维数据数组并导出到 Excel。
主要实现如下功能:
1、根据规则设计EXCEL数据导出模板
2、查询数据,并生成 object[,] 二维数据数组
3、将二维数据数组,其它要输出的数据导出写入到模板 Excel 文件
范例运行环境
操作系统: Windows Server 2019 DataCenter
操作系统上安装 Office Excel 2016
.net版本: .netFramework4.7.2 或以上
开发工具:VS2019 C#
Excel DCOM 配置
请参考我的文章《C# 读取Word表格到DataSet》有对Office DCOM详细配置介绍,这里不再赘述,Excel的对应配置名称如下图所示:
设计实现
组件库引入
方法设计
设计 expExcel 方法实现数据的导出,方法返回生成的全文件路径信息。其调用参数据详细说明见下表:
| 序号 | 参数名 | 类型 | 说明 |
|---|---|---|---|
| 1 | _filename | string | Excel 模板文件的全路径信息 |
| 2 | dataobj | object[,] | 生成的二维数据数组 |
| 3 | ActiveSheetId | int | 指定要导出的活动的SHEETID,序号从1开始 |
| 4 | StartRowId | int | 指定数据导出的开始行ID,序号从1开始 |
| 5 | StartColId | int | 指定数据导出的开始列ID,序号从1开始 |
| 6 | _repls | string[,] | 在EXCEL模板文件里的查找且替换数组,维度1为 key ,维度2 为 value ,系统会根据提供的数组key在模板文件进行查找,并替换对应的 value 值,例如: string[,] _repls=new string[1,2]; _repls[0,0]="模板标题 key "; _repls[0,1]="实际输出的标题值 value"; |
| 7 | drawtype | int | 该值包括0和1。 0:从原始指定起始位置覆盖粘贴数据 1:从原始指定起始位置插入粘贴数据 |
| 8 | AllDataAsString | bool | 默认为 false,是否将所有数据以文本的形式进行输出 |
| 9 | DynamicCols | bool | 默认为false,是否按照二维数据数组动态输出行与列 |
| 10 | DynamicColCfg | ArrayList | 一个对各列进行配置的参数,每个项至少为两个object(一个为列名,一个为列宽),第三个为数据格式(如文本、数值等),例如: ArrayList cfg = new ArrayList(); string _cname = "列名1"; |
| 11 | StartAddress | string | 对 StartRowId 参数和 StartColId 参数 |
生成二维数据数组
如何生成二维数据数组,请参阅我的文章《C# 读取二维数组集合输出到Word预设表格》中的DataSet转二维数组 章节部分。
核心方法实现
代码如下:
public string expExcel(string _filename,object[,] dataobj,int ActiveSheetId,int StartRowId,int StartColId,string[,] _repls,int drawtype,bool AllDataAsString,bool DynamicCols,ArrayList DynamicColCfg,string StartAddress){string AsString=(AllDataAsString?"'":"");string _file="",_path=Path.GetDirectoryName(_filename)+"\\tempbfile\\",_ext="";if(!Directory.Exists(_path)){Directory.CreateDirectory(_path);}_file=Path.GetFileNameWithoutExtension(_filename);_ext=Path.GetExtension(_filename);string _lastfile=_path+System.Guid.NewGuid()+_ext;File.Copy(_filename,_lastfile,true);if(!File.Exists(_lastfile)){return "";}//取得Word文件保存路径object filename=_lastfile;//创建一个名为ExcelApp的组件对象DateTime beforetime=DateTime.Now;Excel.Application excel=new Excel.Application();excel.DisplayAlerts=false;excel.AskToUpdateLinks=false;excel.Visible=true;DateTime aftertime=DateTime.Now;Excel.Workbook xb=excel.Workbooks.Add(_lastfile);Worksheet worksheet = (Worksheet) excel.Worksheets[ActiveSheetId];sheetCount=excel.Sheets.Count;worksheet.Activate();if(_repls!=null){for(int i=0;i<_repls.GetLength(0);i++){worksheet.Cells.Replace(_repls[i,0],_repls[i,1],Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing); }}Excel.Range _range;Excel.Range srange;if(StartAddress!=""){Excel.Range _range_s=worksheet.Range[StartAddress,StartAddress];StartRowId=_range_s.Row;StartColId=_range_s.Column;}int arraywidth=dataobj.GetLength(1);int arrayheight=dataobj.GetLength(0);ArrayList ex_x = new ArrayList();ArrayList ex_y = new ArrayList();ArrayList ex_value = new ArrayList();object _fvalue="";int _maxlen=910; for(int j=0;j<arrayheight;j++){for(int k=0;k<arraywidth;k++){_fvalue=dataobj[j,k];// field valueif(_fvalue==null){continue;}if(_fvalue.GetType().ToString()=="System.String"){if(((string)_fvalue).Length>_maxlen){ex_x.Add(j+StartRowId);ex_y.Add(k+StartColId);ex_value.Add(_fvalue);_fvalue="";}// end maxlen }dataobj[j,k]=(_fvalue.ToString().IndexOf("=")==0?"":AsString)+_fvalue;}//end columns}// end rows if(DynamicCols==true){srange=excel.Range[excel.Cells[StartRowId,StartColId],excel.Cells[StartRowId,StartColId]];for(int i=1;i<arraywidth;i++){_range=excel.Range[excel.Cells[StartRowId,StartColId+i],excel.Cells[StartRowId,StartColId+i]];copyRangeStyle(srange,_range);}}object _copyheight=excel.Range[excel.Cells[StartRowId,StartColId],excel.Cells[StartRowId,StartColId+arraywidth-1]].RowHeight;if(drawtype==1) //取startrow的格式{_range=excel.Range[excel.Cells[StartRowId+1,StartColId],excel.Cells[StartRowId+arrayheight-1,StartColId]];if(arrayheight>1){_range.EntireRow.Insert(Excel.XlInsertShiftDirection.xlShiftDown,Type.Missing);}for(int i=0;i<arraywidth;i++){srange=excel.Range[excel.Cells[StartRowId,StartColId+i],excel.Cells[StartRowId,StartColId+i]];_range=excel.Range[excel.Cells[StartRowId+1,StartColId+i],excel.Cells[StartRowId+arrayheight-1,StartColId+i]];copyRangeStyle(srange,_range);}_range=excel.Range[excel.Cells[StartRowId+1,StartColId],excel.Cells[StartRowId+arrayheight-1,StartColId+arraywidth-1]];_range.RowHeight=_copyheight;}_range=excel.Range[excel.Cells[StartRowId,StartColId],excel.Cells[StartRowId+arrayheight-1,StartColId+arraywidth-1]];_range.get_Resize(arrayheight,arraywidth);_range.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault,dataobj);for(int j=0;j<ex_value.Count;j++){excel.Cells[ex_x[j],ex_y[j]]=ex_value[j].ToString();}if(DynamicCols==true){if(DynamicColCfg!=null){for(int j=0;j<DynamicColCfg.Count;j++){_range=excel.Range[excel.Cells[StartRowId,StartColId+j],excel.Cells[StartRowId,StartColId+j]];object[] cfg=(object[])DynamicColCfg[j];string _title=cfg[0].ToString();_range.Value2=_title;_range=excel.Range[excel.Cells[StartRowId,StartColId+j],excel.Cells[65536,StartColId+j]];if(cfg.Length>1){int _width=int.Parse(cfg[1].ToString());if(_width!=-1){_range.ColumnWidth=_width;}else{_range.ColumnWidth = 255;_range.Columns.AutoFit();}}if(cfg.Length>2){_range.NumberFormatLocal=cfg[2].ToString();}//NumberFormatlocal }}}if (WritePassword != ""){xb.WritePassword = WritePassword;}if (ProtectPassword != ""){worksheet.Protect(ProtectPassword);xb.Protect(ProtectPassword,true,true);}worksheet.SaveAs(@_lastfile, Missing.Value,WritePassword==""?(object)Missing.Value:(object)WritePassword, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);xb.Close(null,null,null);excel.Workbooks.Close();int pid=0;IntPtr a = new IntPtr(excel.Parent.Hwnd);UInt32[] processId = new UInt32[1];GetWindowThreadProcessId((IntPtr)excel.Hwnd,processId);excel.Quit();if(worksheet != null){System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet);worksheet = null;}if(xb != null){System.Runtime.InteropServices.Marshal.ReleaseComObject(xb);xb = null;}if(excel != null){System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);excel = null;}GC.Collect();KillProcessByStartTime("EXCEL",beforetime,aftertime);return _lastfile;}public string KillProcessByStartTime(string processName,DateTime beforetime,DateTime aftertime){Process[] ps = Process.GetProcesses();foreach (Process p in ps) {if(p.ProcessName.ToUpper()!=processName) continue;if(p.StartTime > beforetime && p.StartTime < aftertime){try{p.Kill();}catch(Exception e){return e.Message;}}} return "";}
调用示例
我们设计Web应用中的输出模板(Request.PhysicalApplicationPath + "\\bfile\\excel\\模板.xlsx"),如下图:

object[,] rv = DataSetToOject(); //这个是初始化二维数据数组的string[,] _repls = new string[1, 2];_repls[0, 0] = "<%system.excel.title.dyna.by.craneoffice%>";_repls[0, 1] = "考察对象家庭成员及主要社会关系人基本情况";string ModuleFile = Request.PhysicalApplicationPath + "\\bfile\\excel\\模板.xlsx";string _lastfile = er.Jree(@ModuleFile, rv, 1, 5, 1, _repls, 1, true, false, null);string _url = "/bfile/excel/tempbfile/" + Path.GetFileName(_lastfile);
_lastfile 为最终生成的 excel 数据导出文件全路径地址,_url 为转化的可下载URL地址。
总结
为保持兼容性,本方法支持旧版本的Word97-2003格式,如需要突破65536行限制,我们可以根据实际需要进行设计调整。
本方法支持数据输出行样式的持续复制,即我们可以设置单行样式(如字体大小、颜色、边框等),方法会根据数据行数,循环复制样式进行行输出 。
我们在此仅根据实际项目需要,讲述了一些导出数据到Excel的参数需求,这里仅作参考,欢迎大家评论指教!
相关文章:
C# 实现二维数据数组导出到 Excel
目录 功能需求 范例运行环境 Excel DCOM 配置 设计实现 组件库引入 编辑 方法设计 生成二维数据数组 核心方法实现 调用示例 总结 功能需求 将数据库查询出来的数据导出并生成 Excel 文件,是项目中经常使用的一项功能。本文将介绍通过数据集生成二维…...
nlohmann::json中有中文时调用dump转string抛出异常的问题
问题描述 Winodows下C开发想使用一个json库,使用的nlohmann::json,但是遇到json中使用中文时,转成string,会抛出异常。 nlohmann::json contentJson;contentJson["chinese"] "哈哈哈";std::string test con…...
Unity中InputField一些属性的理解
先看代码: using UnityEngine; using UnityEngine.UI;public class TestInput : MonoBehaviour {[SerializeField]InputField inputField;void Start(){Debug.Log(inputField.text);Debug.Log(inputField.text.Length);Debug.Log(inputField.preferredWidth);Debug…...
【webpack4系列】webpack构建速度和体积优化策略(五)
文章目录 速度分析:使用 speed-measure-webpack-plugin体积分析:使用webpack-bundle-analyzer使用高版本的 webpack 和 Node.js多进程/多实例构建资源并行解析可选方案使用 HappyPack 解析资源使用 thread-loader 解析资源 多进程并行压缩代码方法一&…...
从零开始搭建 PHP
🛠️ 从零开始搭建 PHP 环境:详细教程 PHP(Hypertext Preprocessor)是最流行的后端脚本语言之一,广泛用于构建动态网站和 Web 应用程序。在开始 PHP 开发之前,首先需要搭建 PHP 运行环境。无论你使用的是 …...
【数据结构】8——图3,十字链表,邻接多重表
数据结构8——图3,十字链表,邻接多重表 文章目录 数据结构8——图3,十字链表,邻接多重表前言一、十字链表结构例子 复杂例子 二、邻接多重表(Adjacency Multilist)例子 前言 除了之前的邻接矩阵和邻接表 …...
eth-trunk 笔记
LACP:Link Aggregation Control protocol 链路聚合控制协议 将多条以太网物理链路捆绑在一起成为一条逻辑链路,从而实现增加链路带宽的目的。同时,这些捆绑在一起的链路通过相互间的动态备份,可以有效地提高链路的可靠性 一、配…...
通信工程学习:什么是接入网(AN)中的TF传送功能
接入网(AN)中的TF传送功能 在通信工程中,TF(Transfer Function)传送功能是指为接入网(AN)不同位置之间提供通道和传输介质,以实现数据的有效传输。以下是关于TF传送功能的详细解释&a…...
【JavaEE】IO基础知识及代码演示
目录 一、File 1.1 观察get系列特点差异 1.2 创建文件 1.3.1 delete()删除文件 1.3.2 deleteOnExit()删除文件 1.4 mkdir 与 mkdirs的区别 1.5 文件重命名 二、文件内容的读写----数据流 1.1 InputStream 1.1.1 使用 read() 读取文件 1.2 OutputStream 1.3 代码演示…...
安卓13系统导航方式分析以及安卓13修改默认方式为手势导航 android13修改导航方式
总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.彩蛋1.前言 系统导航方式默认一般是按键的,如果要改成手势的话,我们来看看用户怎么修改的: 设置=>系统=>手势=>系统导航,在这里进行修改。我们来分析下这个流程,并且将其修改为…...
[技术杂谈]暗影精灵8plus电竞版台式机安装和使用注意
最近买回二手台式机准备做深度学习训练模型使用。由于个人不是十分有钱,因此下血本入手一台,不然深度学习玩不转。配置:i9-12900K / 64G d4 3733频率 / 1TSSD2TB机械 / RTX3090 24G显卡 旗舰版 机箱45L超大机箱。买回来后整体不错&#…...
【加密算法基础——AES解密实践】
AES 解密实践 AES 解密是对使用 AES 加密算法加密的数据进行恢复的过程。 常用的解密方式有三种: 在线解密工具:格式比较好控制,但是有些在线工具兼容性不好,有时候无法解出,不知道是自己的密文密钥没找对࿰…...
Spring01
spring框架 spring是轻量级的容器框架 spring framework 1、Spring核心学习内容 IOC、AOp, jdbcTemplate,声明式事务 2、IOC:控制反转,孚以管理部8号对象 3.AOP:切面编程4.JDBCTemplate:是spring提供一套访问数据库的技术,应用性强,相对好理解5.声明式…...
gogps 利用广播星历解算卫星位置matlab函数satellite_orbits详细注解版
主要注释了广播星历计算GPS BDS卫星位置的。 function [satp, satv] satellite_orbits(t, Eph, sat, sbas)% SYNTAX: % [satp, satv] satellite_orbits(t, Eph, sat, sbas); % % INPUT: % t clock-corrected GPS time % Eph ephemeris matrix % sat satellite…...
Oracle按照某一字段值排序并显示,相同的显示序号
Oracle按照某一字段值排序并显示,相同的显示序号 最近的工作遇到对于相同的字段,按照序号去显示值,并对相同的值进行排序 实验了半天,感觉满意的答案,分享给大家 第一种: ROW_NUMBER 语法: ROW_NUMBER() OVER (ORDER BY your_column) AS sequence_number 说明: 根据your_column…...
【Java基础】String详解
文章目录 String一、String 概述1、基本特性2、不可变性3、String、StringBuilder、StringBuffer 二、字符串 创建与内存分配1、字面量 / 双引号2、new关键字3、StringBuilder.toString()4、intern() 方法5、小结 三、字符串 拼接1、常量常量2、变量 拼接3、final变量 拼接4、拼…...
cmd命令
常用命令 查看电脑名称: hostname 查看网卡信息: ipconfig 快速打开网络设置界面: control.exe netconnections 或 rundll32.exe shell32.dll,Control_RunDLL ncpa.cpld 打开防火墙设置: wf.msc 指定网卡设置IP地址&#…...
《中文Python穿云箭量化平台二次开发技术11》股票基本信息获取分析及应用示例【前十大股东占股比例提取及分析】
《中文Python穿云箭量化平台二次开发技术11》股票基本信息获取分析及应用示例【前十大股东占股比例提取及分析】 《中文Python穿云箭量化平台》是纯Python开发的量化平台,因此其中很多Python模块,我们可以自己设计新的量化工具,例如自己新的行…...
OSINT技术情报精选·2024年9月第1周
OSINT技术情报精选2024年9月第1周 2024.8.15版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 1、中国信通院:《大模型落地路线图研究报告(2024年)》 近年来,大模型技术能力不断创出新高,产业应用持续走…...
51单片机应用开发---二进制、十六进制与单片机寄存器之间的关系(跑马灯、流水灯实例)
实现目标 1、掌握二进制与十六进制之间的转换 2、掌握单片机寄存器与二进制、十六进制之间的转换 3、掌握单片机驱动跑马灯、流水灯的原理 一、二进制与十六进制之间的转换 1、二进制 二进制(binary), 是在数学和数字电路中以2为基数的…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
