当前位置: 首页 > 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为基数的…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...