Excel催化剂开源第15波-VSTO开发之DataTable数据导出至单元格区域
上篇提到如何从Excel界面上拿到用户的数据,另外反方向的怎样输出给用户数据,也是关键之处。
VSTO最大的优势是,这双向的过程中,全程有用户的交互操作。
而一般IT型的程序,都是脱离用户的操作,只能让用户准备好数据,离开Excel,或生成数据,要重新打开某文件才能获取到数据结果。
在VSTO中,用户随时在Excel最强UI前端中生产数据,同时也在获得数据结果后,无缝地利用Excel强大的数据处理能力进行数据的再次加工如Vlookup一些其他信息进来,做个图表展示等等。
VSTO程序在用户全程数据链条中,都无缝地参与了,只在用户无法解决的复杂数据转换时,才使用二次开发进行处理,处理完,立即可进行下游的其他操作,用户体验绝对是一流。
言归正传,如何DataTable数据导出至单元格区域
在传统的VBA方法中,有ADO的某个方法CopyToRange,直接将DataRecordset的数据输出至单元格区域。
许多VSTO用户还在抱怨着ADO.Net没有相应的方法而郁闷万方,看完此篇内容,会彻底改观,并且可以彻底放弃ADO这样的落后的技术,拥抱ADO.Net这样与时俱进的专业程序猿使用的技术。
DataTable当然可以很轻松地转换为二维数组,再用Range.Resize的方式将二维数组返回给单元格区域,这不失为一个方法,但此处再次强调,这不是最优的方法。
在VSTO中,提供了ListObject的数据对象,区别于传统VBA中能够使用的ListObject。它是在Microsoft.Office.Tools.Excel命名空间内,是VSTO的宿主项,较传统的ListObject,其命名空间为Microsoft.Office.Interop.Excel,新的ListObject得到很大的增强,其中最明显的是可以绑定数据,类似DataGridView一样。
具体代码实现
先创建一个Microsoft.Office.Tools.Excel命名空间内下的ListObject
public static ListObject CreateNewVSTOListObject(string outputSheetName, bool isRetainExistingTable)
{
Excel.Worksheet sht;
if (isRetainExistingTable)
{
sht = Common.ExcelApp.ActiveWorkbook.Worksheets.Add();
try
{
sht.Name = outputSheetName;
}
catch (Exception)
{
outputSheetName = outputSheetName + DateTime.Now.ToString("yyyyMMddhhmmss");
sht.Name = outputSheetName;
}
}
else
{
try
{
sht = Common.ExcelApp.ActiveWorkbook.Worksheets[outputSheetName];
var displayAlertsStatus = Common.ExcelApp.DisplayAlerts;
if (displayAlertsStatus == true)
{
Common.ExcelApp.DisplayAlerts = false;
sht.Delete();
Common.ExcelApp.DisplayAlerts = true;
}
}
catch (Exception)
{
}
sht = Common.ExcelApp.ActiveWorkbook.Worksheets.Add();
sht.Name = outputSheetName;
}
Worksheet vstoSht = Globals.Factory.GetVstoObject(sht);
ListObject listObject = vstoSht.Controls.AddListObject(sht.Range["A1"], outputSheetName);
return listObject;
}
再将DataTable绑定到ListObject的Datasource上,整个过程结束。
public static void OutputDataToListObject(ListObject listObject, DataTable outputTable, bool isTransDataType=false,string[] mapCols=null)
{
////先提取listDstTable原有公式
Dictionary<string, string> dicListObjectCalColumns = GetCalColumnsOfListObject(listObject);
//激活工作表
Excel.Worksheet actSht = (Excel.Worksheet)listObject.Parent;
actSht.Activate();
listObject.AutoSetDataBoundColumnHeaders = true;
listObject.ShowHeaders = true;
if (mapCols!=null)
{
listObject.MappedColumns = mapCols;
}
//转换列数据格式
if (isTransDataType)
{
////先绑定没有数据的dtEmpty,用于调整列的数字格式
DataTable dtEmpty = outputTable.Clone();
listObject.SetDataBinding(dtEmpty);
TransDataTypeOfListObject(listObject, dtEmpty);
}
////重新绑定数据,用有数据的DataTable
listObject.SetDataBinding(outputTable);
listObject.AutoSetDataBoundColumnHeaders = false;
TransHeaderNameOfListObject(listObject);
listObject.Disconnect();
//追加之前用户加入的公式,有可能会报错的,用Try-Catch来处理
AddCustomCalColumns(listObject, dicListObjectCalColumns);
////自动调整列宽
AutoFitColumnWidth(listObject);
}
大数据下的数据导出
对于数据量较大的数据导出需求时,用ListObject的数据绑定方式导出,有性能瓶颈,可考虑用EPPLUS的方式读写Excel文件。
public static void OutputDataByEpplus(ListObject listObject, DataTable outputTable, bool isTransDataType)
{
var actSht = (Excel.Worksheet)listObject.Parent;
Excel.Workbook actWkb = actSht.Parent;
string shtName = actSht.Name;
string tableName = listObject.Name;
////先提取listDstTable原有公式
Dictionary<string, string> dicListObjectCalColumns = GetCalColumnsOfListObject(listObject);
listObject.Delete();
string filePath = actWkb.FullName;
var listCustomStyleIncludeInfos = StyleSetting.GetCustomStyleIncludeInfos(actWkb);
actWkb.Close(SaveChanges: true);
var fi = new FileInfo(filePath);
using (var p = new ExcelPackage(fi))
{
ExcelWorksheet sht = p.Workbook.Worksheets[shtName];
sht.Cells[1, 1].LoadFromDataTable(outputTable, true, OfficeOpenXml.Table.TableStyles.Light19);
sht.Tables[0].Name = tableName;
p.Save();
};
Excel.Workbook workbook = Common.ExcelApp.Workbooks.Open(filePath);
StyleSetting.SetCustomeStyleIncludInfos(actWkb, listCustomStyleIncludeInfos);
Excel.Worksheet dstSht = workbook.Worksheets[shtName];
dstSht.Activate();
var vstoListObject = Globals.Factory.GetVstoObject(dstSht.ListObjects[tableName]);
//转换格式
if (isTransDataType)
{
TransDataTypeOfListObject(vstoListObject, outputTable);
}
//修改列名
TransHeaderNameOfListObject(vstoListObject);
//追加之前用户加入的公式,有可能会报错的,用Try-Catch来处理
AddCustomCalColumns(vstoListObject, dicListObjectCalColumns);
////自动调整列宽
AutoFitColumnWidth(vstoListObject);
}
结语
通过此篇介绍,给广大开发者特别是VBA转移过来的VSTO开发者带来一些新的方式,不止于只是语法上的更新层面,在.Net环境下开发OFFICE程序时,可以用到许多新的技术和功能,并且较VBA时代的更好用、更易用。
同样最后一句话总结,可以让大家更聚焦在业务逻辑的实现上,通用性的功能,只需找相应的现成轮子帮助即可。
技术交流QQ群
QQ群名:Excel催化剂开源讨论群, QQ群号:788145319
关于Excel催化剂
Excel催化剂先是一微信公众号的名称,后来顺其名称,正式推出了Excel插件,插件将持续性地更新,更新的周期视本人的时间而定争取一周能够上线一个大功能模块。Excel催化剂插件承诺个人用户永久性免费使用!
Excel催化剂插件使用最新的布署技术,实现一次安装,日后所有更新自动更新完成,无需重复关注更新动态,手动下载安装包重新安装,只需一次安装即可随时保持最新版本!
Excel催化剂插件下载链接:https://pan.baidu.com/s/1Iz2_NZJ8v7C9eqhNjdnP3Q


取名催化剂,因Excel本身的强大,并非所有人能够立马享受到,大部分人还是在被Excel软件所虐的阶段,就是头脑里很清晰想达到的效果,而且高手们也已经实现出来,就是自己怎么弄都弄不出来,或者更糟的是还不知道Excel能够做什么而停留在不断地重复、机械、手工地在做着数据,耗费着无数的青春年华岁月。所以催生了是否可以作为一种媒介,让广大的Excel用户们可以瞬间点燃Excel的爆点,无需苦苦地挣扎地没日没夜的技巧学习、高级复杂函数的烧脑,最终走向了从入门到放弃的道路。
最后Excel功能强大,其实还需树立一个观点,不是所有事情都要交给Excel去完成,也不是所有事情Excel都是十分胜任的,外面的世界仍然是一个广阔的世界,Excel只是其中一枚耀眼的明星,还有其他更多同样精彩强大的技术、工具等。*Excel催化剂也将借力这些其他技术,让Excel能够发挥更强大的爆发!
关于Excel催化剂作者
姓名:李伟坚,从事数据分析工作多年(BI方向),一名同样在路上的学习者。
服务过行业:零售特别是鞋服类的零售行业,电商(淘宝、天猫、京东、唯品会)
技术路线从一名普通用户,通过Excel软件的学习,从此走向数据世界,非科班IT专业人士。
历经重重难关,终于在数据的道路上达到技术平原期,学习众多的知识不再太吃力,同时也形成了自己的一套数据解决方案(数据采集、数据加工清洗、数据多维建模、数据报表展示等)。
擅长技术领域:Excel等Office家族软件、VBA&VSTO的二次开发、Sqlserver数据库技术、Sqlserver的商业智能BI技术、Powerbi技术、云服务器布署技术等等。
2018年开始职业生涯作了重大调整,从原来的正职工作,转为自由职业者,暂无固定收入,暂对前面道路不太明朗,苦重新回到正职工作,对Excel催化剂的运营和开发必定受到很大的影响(正职工作时间内不可能维护也不可能随便把工作时间内的成果公布于外,工作外的时间也十分有限,因已而立之年,家庭责任重大)。
和广大拥护者一同期盼:Excel催化剂一直能运行下去,我所惠及的群体们能够给予支持(多留言鼓励下、转发下朋友圈推荐、小额打赏下和最重点的可以和所在公司及同行推荐推荐,让我的技术可以在贵司发挥价值,实现双赢(初步设想可以数据顾问的方式或一些小型项目开发的方式合作)。
技术交流QQ群
QQ群名:Excel催化剂开源讨论群, QQ群号:788145319

关于Excel催化剂
Excel催化剂先是一微信公众号的名称,后来顺其名称,正式推出了Excel插件,插件将持续性地更新,更新的周期视本人的时间而定争取一周能够上线一个大功能模块。Excel催化剂插件承诺个人用户永久性免费使用!
Excel催化剂插件使用最新的布署技术,实现一次安装,日后所有更新自动更新完成,无需重复关注更新动态,手动下载安装包重新安装,只需一次安装即可随时保持最新版本!
Excel催化剂插件下载链接:https://pan.baidu.com/s/1Iz2_NZJ8v7C9eqhNjdnP3Q


取名催化剂,因Excel本身的强大,并非所有人能够立马享受到,大部分人还是在被Excel软件所虐的阶段,就是头脑里很清晰想达到的效果,而且高手们也已经实现出来,就是自己怎么弄都弄不出来,或者更糟的是还不知道Excel能够做什么而停留在不断地重复、机械、手工地在做着数据,耗费着无数的青春年华岁月。所以催生了是否可以作为一种媒介,让广大的Excel用户们可以瞬间点燃Excel的爆点,无需苦苦地挣扎地没日没夜的技巧学习、高级复杂函数的烧脑,最终走向了从入门到放弃的道路。
最后Excel功能强大,其实还需树立一个观点,不是所有事情都要交给Excel去完成,也不是所有事情Excel都是十分胜任的,外面的世界仍然是一个广阔的世界,Excel只是其中一枚耀眼的明星,还有其他更多同样精彩强大的技术、工具等。*Excel催化剂也将借力这些其他技术,让Excel能够发挥更强大的爆发!
关于Excel催化剂作者
姓名:李伟坚,从事数据分析工作多年(BI方向),一名同样在路上的学习者。
服务过行业:零售特别是鞋服类的零售行业,电商(淘宝、天猫、京东、唯品会)
技术路线从一名普通用户,通过Excel软件的学习,从此走向数据世界,非科班IT专业人士。
历经重重难关,终于在数据的道路上达到技术平原期,学习众多的知识不再太吃力,同时也形成了自己的一套数据解决方案(数据采集、数据加工清洗、数据多维建模、数据报表展示等)。
擅长技术领域:Excel等Office家族软件、VBA&VSTO的二次开发、Sqlserver数据库技术、Sqlserver的商业智能BI技术、Powerbi技术、云服务器布署技术等等。
2018年开始职业生涯作了重大调整,从原来的正职工作,转为自由职业者,暂无固定收入,暂对前面道路不太明朗,苦重新回到正职工作,对Excel催化剂的运营和开发必定受到很大的影响(正职工作时间内不可能维护也不可能随便把工作时间内的成果公布于外,工作外的时间也十分有限,因已而立之年,家庭责任重大)。
和广大拥护者一同期盼:Excel催化剂一直能运行下去,我所惠及的群体们能够给予支持(多留言鼓励下、转发下朋友圈推荐、小额打赏下和最重点的可以和所在公司及同行推荐推荐,让我的技术可以在贵司发挥价值,实现双赢(初步设想可以数据顾问的方式或一些小型项目开发的方式合作)。
Excel催化剂开源第15波-VSTO开发之DataTable数据导出至单元格区域的更多相关文章
- Excel催化剂开源第17波-VSTO开发之ADO.Net访问Sqlserver
在Excel催化剂中,独树一帜地推出了Excel与数据库交互功能,目前仅实现了对Sqlserver的交互,在通用型插件中仅此一家,别无其他. 为何会出现这样的局面呢,原因大概有以下几大方面: 和数据库 ...
- Excel催化剂开源第13波-VSTO开发之DataGridView控件几个小坑
Excel催化剂内部大量使用了DataGridView,这其中有一些小坑,花了力气才解决的,在此给广大开发者作简单分享. 为何要使用DataGridView而不是其他控件如ListBox.ListVi ...
- Excel催化剂开源第22波-VSTO的帮助文档在哪里?
Excel催化剂开源第22波-VSTO的帮助文档在哪里? Excel催化剂 2019.01.12 14:10 字数 2930 阅读 55评论 0喜欢 0 编辑文章 对于专业程序猿来说,查找文档不是 ...
- Excel催化剂开源第23波-VSTO开发辅助录入功能关键技术
Excel催化剂开源第23波-VSTO开发辅助录入功能关键技术 Excel催化剂 2019.01.12 14:10* 字数 2948 阅读 41评论 0喜欢 0 编辑文章 在Excel催化剂的几大 ...
- Excel催化剂开源第16波-VSTO开发之脱离传统COM交互以提升性能
在VSTO开发或其他COM技术开发过程中,甚至VBA也是,在和Excel交互中,难免会遇到性能瓶颈问题,COM技术的交互实在太慢,对大量数据读写等操作,耗时太长,容易卡用户界面以为是程序死机等等. 在 ...
- Excel催化剂开源第12波-VSTO开发遍历功能区所有菜单按钮及自定义函数清单
在插件开发过程中,随着功能越来越多,用户找寻功能入口将变得越来越困难,在Excel催化剂 ,将采用遍历所有功能的方式,让用户可以轻松使用简单的查找功能找到想要功能所在位置,查找的范围有:功能按钮的显示 ...
- Excel催化剂开源第10波-VSTO开发之用户配置数据与工作薄文件一同存储
在传统的VBA开发中,若是用的是普通加载项方法,是可以存储数据在xlam上的,若用的是Com加载项方法同时是Addins程序级别的项目开发的,配置文件没法保存到工作薄中,一般另外用配置文件来存放供调用 ...
- Excel催化剂开源第32波-VSTO开发的插件让WPS顺利调用的方法-注册表增加注册信息
VSTO插件开发完成后,鉴于现在WPS用户也不少,很多时候用户没办法用OFFICE软件,只能在WPS环境下办公,VSTO开发的插件,只需增加一句注册表信息,即可让WPS识别到并调用VSTO开发的功能, ...
- Excel催化剂开源第14波-VSTO开发之单元格区域转DataTable
在Excel开发过程中,大部分时候是和Range单元格区域打交道,在VBA开发中,大家都知道的一点是,不能动不动就去遍历所有单元格,那性能是非常糟糕的,很多时候,是需要把整个单元格区域装入数组中再作处 ...
随机推荐
- 在Windows IoT上生成和识别二维码
在Windows IoT生成和识别二维码,实际上由于是UWP上实现,所以,理论上,这些生成和识别二维码的方法也可以在其它平台上运行. 关于二维码的生成有很多库可以实现,比如QRCoder,这个库可以在 ...
- Windows Mount NFS Share from e.g. Linux
Note: Not Stable, so steps below are for reference only ************ Linux Configuration NFS Share 1 ...
- VS2008 环境中完美搭建 Qt 4.7.4 静态编译的调试与发布(很不错,有六张插图说明,修改qmake.conf里的MD参数等)good
为什么要在VS2008中使用QT静态编译呢?很简单,因为VS2008编译器编译出来的文件比mingw编译的要几乎小一半. 好了现在我们来做些准备工作,VS2008自然要安装的,然后打上SP1的补丁.然 ...
- IT安全军火库-转
全球有260万信息安全专业人士,渗透测试工具是他们“安全军火库”中最常使用的装备,但直到最近,可用的渗透测试工具才丰富起来,但这也带来一个问题,挑选合适的渗透测试工具成了一件麻烦事,一个最简单的方法就 ...
- Node 在chrome上调试
先确保node是否安装成功: 然后 1.创建node_module块,并在同一层级创建一个服务: 如server.js: 2.下载调试工具devtool: npm install -g devtool ...
- C++按格式接收输入字符(京东,滴滴,360笔试必用)
头一次起这种标题,为了对得起这个标题,我尽量多写点~ 最近还是一边实习一遍投简历--笔试--面试,然而发现了自己的好多问题. 在答了京东笔试(滴滴,360也是这样的)的题后,发现与腾讯,阿里等公司的不 ...
- __file__、__name__、__dict__方法整理
本文主要介绍__file__.__name__.__dict__三个方法的作用. #01 __file__:打印当前文件的位置. # import os # print(__file__) # 在py ...
- 设计模式之装饰器模式(decorator pattern)
装饰器模式主要对现有的类对象进行包裹和封装,以期望在不改变类对象及其类定义的情况下,为对象添加额外功能.是一种对象结构型模式.需要注意的是,该过程是通过调用被包裹之后的对象完成功能添加的,而不是直接修 ...
- 常用的HTTP状态代码(4xx、5xx)详解
HTTP状态代码常用的如下: 400 无法解析此请求. 401.1 未经授权:访问由于凭据无效被拒绝. 401.2 未经授权: 访问由于服务器配置倾向使用替代身份验证方法而被拒绝. 401.3 未经授 ...
- 基于STM32F429和Cube的主从定时器多通道输出固定个数的PWM波形
主从定时器的原理已在上篇博文: 基于STM32F429+HAL库编写的定时器主从门控模式级联输出固定个数PWM脉冲的程序 讲解了,这篇重点就讲如何实现多通道的PWM级联输出. 1.软件环境 Keil5 ...