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催化剂插件使用最新的布署技术,实现一次安装,日后所有更新自动更新完成,无需重复关注更新动态,手动下载安装包重新安装,只需一次安装即可随时保持最新版本!

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催化剂插件使用最新的布署技术,实现一次安装,日后所有更新自动更新完成,无需重复关注更新动态,手动下载安装包重新安装,只需一次安装即可随时保持最新版本!

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催化剂一直能运行下去,我所惠及的群体们能够给予支持(多留言鼓励下、转发下朋友圈推荐、小额打赏下和最重点的可以和所在公司及同行推荐推荐,让我的技术可以在贵司发挥价值,实现双赢(初步设想可以数据顾问的方式或一些小型项目开发的方式合作)。

原文地址:https://www.cnblogs.com/ExcelCuiHuaJi/p/10579027.html

时间: 2024-10-25 07:10:51

Excel催化剂开源第15波-VSTO开发之DataTable数据导出至单元格区域的相关文章

Excel催化剂开源第17波-VSTO开发之ADO.Net访问Sqlserver

在Excel催化剂中,独树一帜地推出了Excel与数据库交互功能,目前仅实现了对Sqlserver的交互,在通用型插件中仅此一家,别无其他. 为何会出现这样的局面呢,原因大概有以下几大方面: 和数据库交互的使用群体太窄,除非极个别数据分析师会用到这个问题的确存在,在Excel群体中,能够有机会接触到数据库层面的聊聊无几,当属于最上层高级Excel用户才会涉猎,对Excel催化剂来说,本来群体已定位为重度Excel高级用户使用,有此功能才显得插件的饱满性. 开发者本身不懂数据库,更无从开发数据库相

Excel催化剂开源第16波-VSTO开发之脱离传统COM交互以提升性能

在VSTO开发或其他COM技术开发过程中,甚至VBA也是,在和Excel交互中,难免会遇到性能瓶颈问题,COM技术的交互实在太慢,对大量数据读写等操作,耗时太长,容易卡用户界面以为是程序死机等等. 在专业程序猿开发群体,极少直接用COM的方式来访问Excel文件,都是以其他的非COM如最为流行的NPOI和EPPLUS类库的方式访问,并且是免费的可用于商业项目的. 在VSTO中调用NPOI和EPPLUS,又是怎样一翻境界呢?因Excel催化剂主要是为数据分析群体服务,其中大量的场景是面积大数据量的

Excel催化剂开源第14波-VSTO开发之单元格区域转DataTable

在Excel开发过程中,大部分时候是和Range单元格区域打交道,在VBA开发中,大家都知道的一点是,不能动不动就去遍历所有单元格,那性能是非常糟糕的,很多时候,是需要把整个单元格区域装入数组中再作处理的. 在VSTO开发中,难不成还要用VBA这套老掉牙的东西来做吗?VBA的二维数组在.Net的世界中,真的一无是处,太多比它好用的东西存在,其中笔者最喜欢用的是DataTable这样的结构化的数据结构. 从单元格到DataTable,其实也就几句代码的事情,当数据进入到DataTable后,可以使

Excel催化剂开源第40波-Excel插入图片做到极致的效果

不知道是开发人员的自我要求不高还是用户的使用宽容度足够大,在众多Excel插入图片的版本中,都没有考虑到许多的可大幅度提升用户体验的细节处理. Excel催化剂虽然开发水平有限,但也在有限的能力下,尽最大的努力做到自己可以过关的出街成品. 此篇着重谈下思路性的问题,代码因为太久远之前写的,现在看回也是一坨坨的,真需要时可能重新写一轮更方便. Excel插入图片的细节追求 可能在之前的文章中,也偶尔做了一些分享,自己也不太记得分享过哪些了,这里再重新梳理下,有重复提及的部分就权当复习好了. 一.插

Excel催化剂开源第3波-修复ExcelCom加载项失效问题及WPS可调用Com加载项的方法

为了还原一个干净无侵扰的网络世界,本文将不进行大规模地分发,若您觉得此文有用,不妨小范围地分享到真正有需要的人手中 功能概述 修复ExcelCom加载项常见问题,如每次需重新勾选COM加载项或COM加载项被列入禁用清单中不用使用,同时也提供让WPS计用COM加载项的方法 使用场景 因用户在使用COM技术开发的加载项过程中,难免各种意外操作,致使加载项处理非活动状态或失效状态,虽然可以通过界面的方式去解决,但步骤偏多,对普通用户来说,较难以去理解及操作,将其封装成一个exe文件,让用户自行双击运行

Excel催化剂开源第5波-任务窗格在OFFICE2013中新建文档不能同步显示问题解决

在OFFICE2013及之后,使用了单文档界面技术,不同于以往版本可以共享任务空格.功能区.所以当开发任务窗格时,需要考虑到每一个工作薄都关联一个任务窗格. 背景介绍 单文档界面摘录官方定义如下:对 Excel 2013 中的单文档界面 (SDI) 进行更改对可编程性具有一定影响.SDI 意味着每个工作簿都将有其自己的顶级应用程序窗口,并将有自己的相应功能区. 带来的好处是不同工作薄可以精细控制不同的显示,例如工作薄A,显示功能区Tab1,工作薄B显示功能区Tab2,区分对待不同文档所使用的功能

Excel催化剂开源第4波-ClickOnce部署要点之导入数字证书及创建EXCEL信任文件夹

Excel催化刘插件使用Clickonce的部署方式发布插件,以满足用户使用插件过程中,需要对插件进行功能升级时,可以无痛地自动更新推送新版本.但Clickonce部署,对用户环境有较大的要求,前期首次安装,比较波折,但相对于后续的自动更新的回报,笔者自我感觉还是很值得的.Clickonce部署过程中,要求导入数字证书和设置Excel共享路径这两个步骤,本篇开源代码主要讲述这个过程的自动化处理的代码实现,同样用的是Console程序. 为了还原一个干净无侵扰的网络世界,本文将不进行大规模地分发,

Excel催化剂开源第51波-Excel催化剂遍历单元格操作性能保障

在Excel催化剂推出的这一年多时间里,经常性听到一种声音,大概意思是真正会写代码的人,都不会看上Excel催化剂写出来的功能,自己造一个更舒服贴心,仿佛会一点VBA就可以天下无敌一般,也好像Excel催化剂出的所有的功能,在他们眼中都是幼儿园级别,过家家玩玩而已. 这里不对此看法置评,只用事实说话,看看会一点VBA的人,能否造出以下的超强性能保障的代码功能来. 遍历单元格性能问题 学过VBA的群体,都知道遍历单元格是一个很慢的过程,最好将其放进数组中再遍历. 为何会慢这个问题,可能就没有深入研

Excel催化剂开源第36波-图片Exif信息提取,速度超快,信息超全

Excel催化剂在文件处理方面,功能做到极致,但其实很大功劳都是引用一些开源社区的轮子库,不敢独占好处,此篇给大家分享下抓取图片的Exif信息的好用的轮子. 此篇对应的Excel催化剂功能实现:第83波-遍历文件夹内文件信息特别是图像.音视频等特有信息 https://www.jianshu.com/p/ad98adc64f0b 当然再次强调,找东西尽量用google,百度是非常低效,找出来的代码,好多也不适用,吐槽下百度最喜欢收录CSDN的文章,只是物以类聚,垃圾对垃圾,广告婊子一个.真要搜索