随心所欲

做个幸福的人
posts - 147, comments - 1402, trackbacks - 28, articles - 0
  博客园 :: 首页 :: 新随笔 ::  :: 订阅 订阅 :: 管理

Excel集成种种

Posted on 2007-03-27 14:51 随心所欲 阅读(4326) 评论(35)  编辑 收藏 网摘 所属分类: MS Office

最近有些项目在做集成,和Excel之类的。所遇到的问题如下:

Win下如何操作

如何处理Excel进程

如何制作AddIn

如何在Web中应用

其他..

 

//

Win下的应用

Excel.Application _excelApp = new Excel.Application();

Excel._Workbook reportWB = null;

Excel._Worksheet reportWS = null;

try

{
    
reportWB = (Excel._Workbook)Schedule.ExcelApp.Workbooks._Open(fileReport, 0, false, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true);

     reportWS = (Excel._Worksheet)reportWB.Worksheets["Sheet1"];

…………

………

………

        reportWB.Save();

   }

  Marshal.ReleaseComObject(reportWB);

  Marshal.ReleaseComObject(reportWS);

  reportWB = null;

reportWS = null;

ExcelApp.Workbooks.Close();

ExcelApp.Quit();
  System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp);
  GC.Collect();

只是这个Excel进程关闭起来比较麻烦,另作论述。

关于简单的操作

赋值:

reportWS.get_Range("D3" , "D3" ).Value2 =”xxx”;

插入行列:

(reportWS.Rows[beginRow, Missing.Value] as Excel.Range).Insert(Excel.XlDirection.xlDown, Missing.Value);

复制行列

reportWS.get_Range("A3", "I4").Copy(Missing.Value);

粘贴行列:

reportWS.get_Range("A4" "I5").PasteSpecial(Excel.XlPasteType.xlPasteAll, Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, Missing.Value, Missing.Value);

公式:

reportWS.get_Range("D3" , "D3" ).Value2 =”=sum(D1:D2)”;

也有其他高手提供的操作Excel的类库,但是有时候需要自己做比较精细的控制,所以一般都是自己去做这些操作。

注意:

  1:复制的时候可以附带上单元格的格式

  2:公式的循环引用设置。不然的话就会有很烦人的提示。

关于安装:

  1:需要安装一个XP下的接口oxpPIA。可到微软网站下载

  2:解压缩oxpPIA注册时,需要一个程序gacutil.exe

 

关于关闭Excel进程的问题

Win/Web下,都可以生成一个ExcelApplication对象。但是这个对象在关闭时可能会遇到问题。主要是,即使执行了释放对象的操作,也很难把这个实例关掉。每次去TaskMan里面看看,还都在内存里面。

解决方法

  1:只用一个全局的Application对象。关不掉,就不关了。所有的地方都用这个App来打开新的Worbook,这样,只要最后关掉这些Workbook,Worksheet就可以了。只有一个实例也不会占用很多的资源。

  2:彻底关掉这个进程

  Process[] excelPro;

        excelPro = Process.GetProcessesByName("Excel");

        foreach (Process myProcess in excelPro)

        {

            myProcess.Kill();

        }

有点暴力,但是管用。

 

制作Add-In

建立项目:

vs.studio里面有模版,建立一个AddIn比较简单。

刚开始的时候,我用的Express版,就只能手工写这些代码了。这个Connector也就是继承自Extensibility.IDTExtensibility2的一个实现而已。

其实关键就在那一个Connector上。还有就是如何注册这个控件。原来在VB里面开发完之后,Excel还识别他是一个Dcom,但是后来用C#开发的居然无法识别。其怪也哉。最后直接通过写注册表实现。

调试:

调试在vs.studio里面也不是问题,只要设置项目debug启动参数就可以:项目/属性/Debug/Start Action/Start external program/ 选择Excel.exe的位置就可以

Web下的应用

Web下边写Excel,除去了用上述Win下的操作之外,也还有其他方式来实现,那就是直接写Response输出,进而演化出来写Html格式的Excel数据。

1:直接输出到Response 这个方法,就是直接生成一个Html页面,然后把该页面的type修改一下,变成application/ms-excel,这样,客户端的IE会把这个html页面在Excel中打开。具体可以看 http://www.cnblogs.com/caizinet/

用这个方法输出的话,可以直接把页面上所有内容都输出到Excel。包括各类格式和数据。

但是,也有点小问题:有时候会把界面上所有的东西都在Excel中里面显示。

2:直接输出到.xls文件,让客户下在这个文件。

   这次输出的.xls文件,也是用html来实现,那就是直接把html格式的数据保存成xls文件,这样的话,用户就可以直接下在这个文件了。

   输出的数据可以直接是<Table>

   a:) strData=”<Table>………….. “

b:) string file ,  File.Write(strData)

c:) Response.Redirect(file);

这个实现还有个有意思的地方,那就是可以直接使用公式。<table><td>=Sum(A1:A3)</td></table>

 

更多:使用宏,而不是IE来做客户端

有朋友正在开发一套程序,就是因为所处理的数据过大,导致IE加载后占用内存近500M的情况。后来他使用了宏处理,直接使用Excel来做客户端。这也是个很不错的方法。

 

Feedback

#1楼    回复  引用  查看    

2007-03-27 15:15 by aspnetx      
最后一个没大看懂

我喜欢用宏录制的功能来参考office是如何工作的
然后仿照用代码实现,可以解决一些棘手的需求

#2楼 [楼主]   回复  引用  查看    

2007-03-27 15:26 by 随心所欲      
@aspnetx
宏+script. 加载远程的数据。

您使用宏的方法也真的很不错,学习。

#3楼    回复  引用  查看    

2007-03-27 16:11 by Cure      
总结得不错

解压缩oxpPIA,注册时,需要一个程序gacutil.exe
-----------------------
gacutil.exe 在.netframework里就有的。

#4楼 [楼主]   回复  引用  查看    

2007-03-27 16:30 by 随心所欲      
@Cure
没有,搜索过好几遍。
一开始我是通过安装 sdk2.0来得到的(400M啊,就为了找这个玩意)。
也可能是因为我是俺装的Express版本的缘故。

#5楼    回复  引用  查看    

2007-03-27 19:10 by e表      
excel集成是比较麻烦. 我用c#写了一个直接对excel文件进行读写的ebexcel.dll,这样客户端和服务器端就都不需要安装excel软件了. 可以在 http://webreport.fcsoft.com.cn 看到演示.

#6楼    回复  引用    

2007-03-27 19:12 by hyifeng [未注册用户]
Process[] excelPro;
excelPro = Process.GetProcessesByName("Excel");
foreach (Process myProcess in excelPro)
{
myProcess.Kill();
}

千万不要这样做。除非你肯定用户不会在使用EXCEL

#7楼 [楼主]   回复  引用  查看    

2007-03-27 19:21 by 随心所欲      
@hyifeng
这种软件不会放到哪个客户自己的pc上的,一定会有专门的机器运行。

#8楼 [楼主]   回复  引用  查看    

2007-03-27 19:26 by 随心所欲      
@e表
看起来很不错的说!
价格几何?

#9楼    回复  引用  查看    

2007-03-27 21:56 by Cure      
@随心所欲
gacutil.exe是.netframework的全局程序集缓存工具,
刚才看了下,1.1版本里就在framework的安装目录,2.0的倒确实是没找到,但是在命令行里可以执行,怪了

#10楼 [楼主]   回复  引用  查看    

2007-03-28 09:52 by 随心所欲      
@Cure
有劳了。
看来2.0里面没有带。不过程序也不大,发布的时候copy过去也不过份。

#11楼    回复  引用    

2007-03-28 10:34 by sharper.shen [未注册用户]
Process[] excelPro;
excelPro = Process.GetProcessesByName("Excel");
foreach (Process myProcess in excelPro)
{
myProcess.Kill();
}
存在权限问题,Network Service 用户不一定能够执行这样的操作。
Excel,word,PowerPoint等Office Application在web应用下跑, 不是个好策略。

#12楼 [楼主]   回复  引用  查看    

2007-03-28 10:59 by 随心所欲      
@sharper.shen
是的。
这种情况最好只在Win下。如果是web用户,在用域内用户登陆模式的时候也可能实现。要是form验证,怕是不行的。

#13楼 [楼主]   回复  引用  查看    

2007-03-28 11:01 by 随心所欲      
@sharper.shen
至于策略问题:
1:简单的输出可以使用Web
2:复杂的操作(读Excel)多是以Web为界面,做WinService作后台执行。

#14楼    回复  引用    

2007-03-28 17:47 by Javafun [未注册用户]
关注这个问题,一只没有找到好的方法去kill word,excel进程

#15楼    回复  引用    

2007-03-28 18:09 by firefox [未注册用户]
挺有价值

#16楼    回复  引用    

2007-03-29 12:43 by pucumt [未注册用户]
小伙子还要加油,漏洞比较多,但作为参考或处理方法却有价值

#17楼 [楼主]   回复  引用  查看    

2007-03-29 13:08 by 随心所欲      
@pucumt
呵呵,那还请多指教。

#18楼    回复  引用    

2007-05-10 17:58 by ukyoxh [未注册用户]
增加点点东西
System.Diagnostics.Process [] PROC = Process.GetProcessesByName("EXCEL");
foreach(System.Diagnostics.Process PK in PROC)
{
//仅当进程有图形界面时,该进程才具有与其关联的主窗口。如果关联进程没有主窗口(因而 MainWindowHandle 为零),免得误伤
if(PK.MainWindowTitle.Length==0)
PK.Kill();
}

#19楼 [楼主]   回复  引用  查看    

2007-05-10 18:22 by 随心所欲      
@ukyoxh
没测试过,不过如果真的可以,这将是一个非常好的方法。
或者这样,凡是我的程序打开的Excel的进程,我都把Title设置成“AutoCreateByApp”,这样就更有的放矢了

#20楼    回复  引用    

2007-07-15 08:12 by 火狐 [未注册用户]
@ukyoxh
没测试过,不过如果真的可以,这将是一个非常好的方法。
或者这样,凡是我的程序打开的Excel的进程,我都把Title设置成“AutoCreateByApp”,这样就更有的放矢了

#21楼    回复  引用    

2007-07-15 08:12 by 火狐 [未注册用户]
增加点点东西
System.Diagnostics.Process [] PROC = Process.GetProcessesByName("EXCEL");
foreach(System.Diagnostics.Process PK in PROC)
{
//仅当进程有图形界面时,该进程才具有与其关联的主窗口。如果关联进程没有主窗口(因而 MainWindowHandle 为零),免得误伤
if(PK.MainWindowTitle.Length==0)
PK.Kill();
}

#22楼    回复  引用    

2007-07-15 08:13 by 火狐 [未注册用户]
c# 实现Word联接Excel的MailMerge功能

#23楼 [楼主]   回复  引用  查看    

2007-07-16 21:11 by 随心所欲      
@火狐
谢谢分享,真是不错的想法。

#24楼    回复  引用    

2007-08-20 06:43 by DHC [未注册用户]
说的不错~~~谢谢分享

#25楼    回复  引用    

2007-09-29 19:00 by 火狐 [未注册用户]
2007-07-16 21:11 by 随心所欲

不客气 大家多多讨论

#26楼    回复  引用    

2007-09-30 23:55 by 火狐 [未注册用户]
很好的文章

#27楼    回复  引用    

2007-10-14 13:21 by dhc [未注册用户]
很好 谢谢

#28楼    回复  引用    

2007-10-25 11:07 by dhc [未注册用户]
不能对基于Forms验证的Web应用进行爬网

#29楼    回复  引用    

2007-10-25 11:09 by 征途私服 [未注册用户]
在vs.studio里面有模版,建立一个AddIn比较简单。

#30楼 [楼主]   回复  引用  查看    

2007-10-25 12:29 by 随心所欲      
@dhc
这是另外的课题了.

#31楼 [楼主]   回复  引用  查看    

2007-10-25 12:30 by 随心所欲      
@征途私服
不是作AddIN,而是在web或者其他地方使用Excel的功能.

#32楼    回复  引用    

2007-11-21 14:08 by 国际电话卡 [未注册用户]
oxpPIA楼主能否提供以下下载地址,偶没有找到!

#33楼 [楼主]   回复  引用  查看    

2007-11-21 17:50 by 随心所欲      
@国际电话卡
http://www.microsoft.com/downloads/details.aspx?FamilyId=C41BD61E-3060-4F71-A6B4-01FEBA508E52&displaylang=en

google搜索“oxpPIA”第一个页面就是。

#34楼    回复  引用    

2007-12-03 18:38 by 非主流 [未注册用户]
看看

#35楼    回复  引用    

2008-09-12 17:51 by yyp [未注册用户]
"'''''''''''''''''''''''''''''''''''
增加点点东西
System.Diagnostics.Process [] PROC = Process.GetProcessesByName("EXCEL");
foreach(System.Diagnostics.Process PK in PROC)
{
//仅当进程有图形界面时,该进程才具有与其关联的主窗口。如果关联进程没有主窗口(因而 MainWindowHandle 为零),免得误伤
if(PK.MainWindowTitle.Length==0)
PK.Kill();
}
''''''''''''''''''''''''''''''''''
这个方法,有个问题,如果有几个各户端执行,产生多个EXCEL进程(没有主窗口),其中一个关闭其他正在运行的,显然有问题么。

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-03-27 15:07 编辑过
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:

相关链接:
 
Google