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

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的对应配置名称如下图所示:

1072f229d76a5715dcb6542d89b41c06.png

  

设计实现

组件库引入

796f3a082e903b296b62ca33d4d5dcd8.png

方法设计

设计  expExcel 方法实现数据的导出,方法返回生成的全文件路径信息。其调用参数据详细说明见下表: 

序号参数名类型说明
1_filenamestringExcel 模板文件的全路径信息
2dataobjobject[,]生成的二维数据数组
3ActiveSheetIdint指定要导出的活动的SHEETID,序号从1开始
4StartRowIdint指定数据导出的开始行ID,序号从1开始
5StartColIdint指定数据导出的开始列ID,序号从1开始
6_replsstring[,]

在EXCEL模板文件里的查找且替换数组,维度1为 key ,维度2 为 value ,系统会根据提供的数组key在模板文件进行查找,并替换对应的 value 值,例如:

string[,] _repls=new string[1,2];

_repls[0,0]="模板标题 key "; 

_repls[0,1]="实际输出的标题值 value";

7drawtypeint

该值包括0和1。

0:从原始指定起始位置覆盖粘贴数据

1:从原始指定起始位置插入粘贴数据

8AllDataAsStringbool默认为 false,是否将所有数据以文本的形式进行输出
9DynamicColsbool默认为false,是否按照二维数据数组动态输出行与列
10DynamicColCfgArrayList

一个对各列进行配置的参数,每个项至少为两个object(一个为列名,一个为列宽),第三个为数据格式(如文本、数值等),例如:

ArrayList cfg = new ArrayList();

string _cname = "列名1";
string _width = "-1";   //-1 表示自动适应列宽
cfg.Add(new object[] { _cname, _width });

11StartAddressstring对 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"),如下图:

39923a9f7e9a43e2939112cca8ee9a66.png

如图  <%system.excel.title.dyna.by.craneoffice%> ,表示要替换的标题 key ,下面的二维表格,表示预设好的输出列,下面的行即为数据输出行,在这里,我们预设要从第1列第5行输出数据。以下是调用的示例代码:

 

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 文件&#xff0c;是项目中经常使用的一项功能。本文将介绍通过数据集生成二维…...

nlohmann::json中有中文时调用dump转string抛出异常的问题

问题描述 Winodows下C开发想使用一个json库&#xff0c;使用的nlohmann::json&#xff0c;但是遇到json中使用中文时&#xff0c;转成string&#xff0c;会抛出异常。 nlohmann::json contentJson;contentJson["chinese"] "哈哈哈";std::string test con…...

Unity中InputField一些属性的理解

先看代码&#xff1a; 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构建速度和体积优化策略(五)

文章目录 速度分析&#xff1a;使用 speed-measure-webpack-plugin体积分析&#xff1a;使用webpack-bundle-analyzer使用高版本的 webpack 和 Node.js多进程/多实例构建资源并行解析可选方案使用 HappyPack 解析资源使用 thread-loader 解析资源 多进程并行压缩代码方法一&…...

从零开始搭建 PHP

&#x1f6e0;️ 从零开始搭建 PHP 环境&#xff1a;详细教程 PHP&#xff08;Hypertext Preprocessor&#xff09;是最流行的后端脚本语言之一&#xff0c;广泛用于构建动态网站和 Web 应用程序。在开始 PHP 开发之前&#xff0c;首先需要搭建 PHP 运行环境。无论你使用的是 …...

【数据结构】8——图3,十字链表,邻接多重表

数据结构8——图3&#xff0c;十字链表&#xff0c;邻接多重表 文章目录 数据结构8——图3&#xff0c;十字链表&#xff0c;邻接多重表前言一、十字链表结构例子 复杂例子 二、邻接多重表&#xff08;Adjacency Multilist&#xff09;例子 前言 除了之前的邻接矩阵和邻接表 …...

eth-trunk 笔记

LACP&#xff1a;Link Aggregation Control protocol 链路聚合控制协议 将多条以太网物理链路捆绑在一起成为一条逻辑链路&#xff0c;从而实现增加链路带宽的目的。同时&#xff0c;这些捆绑在一起的链路通过相互间的动态备份&#xff0c;可以有效地提高链路的可靠性 一、配…...

通信工程学习:什么是接入网(AN)中的TF传送功能

接入网&#xff08;AN&#xff09;中的TF传送功能 在通信工程中&#xff0c;TF&#xff08;Transfer Function&#xff09;传送功能是指为接入网&#xff08;AN&#xff09;不同位置之间提供通道和传输介质&#xff0c;以实现数据的有效传输。以下是关于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电竞版台式机安装和使用注意

最近买回二手台式机准备做深度学习训练模型使用。由于个人不是十分有钱&#xff0c;因此下血本入手一台&#xff0c;不然深度学习玩不转。配置&#xff1a;i9-12900K / 64G d4 3733频率 / 1TSSD2TB机械 / RTX3090 24G显卡 旗舰版 机箱45L超大机箱。买回来后整体不错&#…...

【加密算法基础——AES解密实践】

AES 解密实践 AES 解密是对使用 AES 加密算法加密的数据进行恢复的过程。 常用的解密方式有三种&#xff1a; 在线解密工具&#xff1a;格式比较好控制&#xff0c;但是有些在线工具兼容性不好&#xff0c;有时候无法解出&#xff0c;不知道是自己的密文密钥没找对&#xff0…...

Spring01

spring框架 spring是轻量级的容器框架 spring framework 1、Spring核心学习内容 IOC、AOp, jdbcTemplate,声明式事务 2、IOC:控制反转&#xff0c;孚以管理部8号对象 3.AOP:切面编程4.JDBCTemplate:是spring提供一套访问数据库的技术,应用性强&#xff0c;相对好理解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命令

常用命令 查看电脑名称&#xff1a; hostname 查看网卡信息&#xff1a; ipconfig 快速打开网络设置界面&#xff1a; control.exe netconnections 或 rundll32.exe shell32.dll,Control_RunDLL ncpa.cpld 打开防火墙设置&#xff1a; wf.msc 指定网卡设置IP地址&#…...

《中文Python穿云箭量化平台二次开发技术11》股票基本信息获取分析及应用示例【前十大股东占股比例提取及分析】

《中文Python穿云箭量化平台二次开发技术11》股票基本信息获取分析及应用示例【前十大股东占股比例提取及分析】 《中文Python穿云箭量化平台》是纯Python开发的量化平台&#xff0c;因此其中很多Python模块&#xff0c;我们可以自己设计新的量化工具&#xff0c;例如自己新的行…...

OSINT技术情报精选·2024年9月第1周

OSINT技术情报精选2024年9月第1周 2024.8.15版权声明&#xff1a;本文为博主chszs的原创文章&#xff0c;未经博主允许不得转载。 1、中国信通院&#xff1a;《大模型落地路线图研究报告(2024年)》 近年来&#xff0c;大模型技术能力不断创出新高&#xff0c;产业应用持续走…...

51单片机应用开发---二进制、十六进制与单片机寄存器之间的关系(跑马灯、流水灯实例)

实现目标 1、掌握二进制与十六进制之间的转换 2、掌握单片机寄存器与二进制、十六进制之间的转换 3、掌握单片机驱动跑马灯、流水灯的原理 一、二进制与十六进制之间的转换 1、二进制 二进制&#xff08;binary&#xff09;&#xff0c; 是在数学和数字电路中以2为基数的…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...