1.控件要实现的功能
用户可以选择一个excel文件(2003或2007), 输入excel里的一个sheet名, 点Start按钮将该sheet中的数据通过ole/db解析为recordset, 之后自动将recordset存成xml, 然后自动调用一个web service, 将xml数据发送出去, 这个ActiveX控件的任务就完成了, web service那边负责将xml解析成.Net DataTable, 然后再进行校验, 入库等操作...
控件截图如下:
2.为什么要这么做?
一般来说, 只要写一个webform, 让用户选择excel2007文件, 然后服务器端调用oledb12来将excel转为dataset即可, 但前提是网站得运行在32位操作系统上, 而我们的网站是运行在64位操作系统上的, 这样一来, webform会报出一个错误, 即未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序这个错误, 经过查找, 发现微软不提供64下oledb12程序, 微软也不提倡在服务器端用oledb转化excel, 微软提倡在客户端用, 而这似乎是一个长期政策,起码短时间看不会改变的迹象。所以, 在64位系统下的webform里直接调oledb12将excel转dataset的路走不通了.
如果换个思路, 如果将网站转为兼容32的模式运行, 可以解决这个问题, 但又带来系统性能下降的问题, 所以不能考虑.
所以, 只能考虑用其他办法,比如:
2.1 客户端技术,创建.Net的用户控件, 然后把它放到webform中,用它来调用客户端的oledb转换dataset,然后再调webservice把数据传回来。
2.2 客户端技术,用老的Vb6创建Activex控件,然后把它放到webform中,用它来调用客户端的oledb转换dataset再调webservice.
2.3 服务器端技术,单独建一个兼容32位的网站专门用来上传解析数据, 然后再调webservice;
比较一下: .Net的用户控件要求客户端得安装.Net Framework,有点麻烦;新建网站需要考虑维护及访问权限的事情, 而创建Vb6 Activex控件则没有这些烦恼,所以就先实现了Vb6创建Activex控件的方案,顺便用此文总结一下思路。
3.Vb6创建Activex控件步骤
3.1 安装visual studio 6.0
3.2 创建activex control project.
3.3 控件布局
两个文本框及Label: 一个用来显示选择的文件名,一个用来输入要解析的sheet名字.
一个CommonDialog, 用来选择文件用。
两个按钮:一个用来弹出选择文件的CommonDialog,一个用来开始解析数据及最后叫Web Service.
3.4 ole/db解析出recordset
选择excel文件后,根据扩展名来决定使用哪个ole/db版本。
2007用 strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & txtFileName.Text & ";Extended Properties='Excel 12.0;HDR=YES'"
2003用 strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & txtFileName.Text & ";Extended Properties=""Excel 8.0;HDR=Yes;"";"
3.5 recordset存成xml
读出Recordset后,将它写入流stream,然后再读出里面的xml格式数据。
代码如下:
'open recordset
Set conn = New ADODB.Connection
conn.Open strConn
strSql = "select * from [" & uploadSheetName & "$]"
conn.Execute strSql
Set rs = New ADODB.Recordset
rs.Open strSql, conn, adOpenStatic, adLockOptimistic
'save recordset to stream and xml string
rs.Save stream, PersistFormatEnum.adPersistXML
stream.Flush
stream.Position = 0
dim strXML = stream.ReadText(stream.Size)
Set rs = Nothing
3.6 增加属性参数, 使用接口向导, 这样可以从外面传参数到控件里.
点击Add-Ins/Add-In Manager菜单,然后选择VB6 Activex Ctrl Interface Wizard,双击, OK,然后就可以在Add-Ins菜单下看到Activex Ctrl Interface Wizard菜单项了,点击即可打开,在里面增加一个WebService
URL的属性参数, 这样可以从外面传参数到控件里,这样控件就灵活点了。
3.7 Call web service.
创建XMLHTTP对象,将xml数据post到web service的url中去。
代码如下:
Set oHTTP = New XMLHTTP
oHTTP.Open "POST", strURL, False
oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oHTTP.send (strPost)
3.8 处理返回值.
用MsgBox将web service的xml的返回值提示出来。
代码如下:
While oHTTP.readyState <> 4
Wend
strResult = oHTTP.responseText
Set xmlDoc = New MSXML2.DOMDocument60
xmlDoc.loadXML strResult
strResult = xmlDoc.childNodes(1).Text
MsgBox strResult, vbOKOnly, "Message"
3.9 使用打包安装工具制作cab包
点击Add-Ins/Add-In Manager菜单,然后选择Package and Deployment Wizard,双击, OK,然后就可以在Add-Ins菜单下看到Package and Deployment Wizard菜单项了,点击即可打开, 在里面点击Package按钮,选
择创建inernet package类型(生成.cab), 然后按提示即可。
注意:如果此步出错,无法完成,就说明visual studio没装全,找个全的重装即可。
3.10 测试html页面, 里面加param参数.
在项目下找到生成的Package目录,里面有html页面,里面包含activex的调用例子,只要在里面增加param,写入web service实际的url即可。
代码如下:
<OBJECT ID="BatchUplo" CLASSID="CLSID:AB32AFF2-3F95-4BAF-9F55-125399004DA0" CODEBASE="BatchUploadExcelPrj.CAB#version=2,0,0,0" width="600" height="200">
<PARAM NAME="WSURL" VALUE="http://ipaddress/WebServiceDirecotry/WebServiceName.asmx/WebServiceMethodName">
</OBJECT>
3.11 记住, 控件的宽度和高度一定要设置,否则就有可能白页面什么都不显示。
3.12 IE中要添加信任站点,并将activex的下载,运行等选项打开。
3.13 测试, 当然,如果web service有安全验证,则另行处置,done。
4.总结
这个控件现在基本就算完成了, 但是,如果调用的web service需要验证才能访问可能就会有麻烦了,因为从activex控件里调用webservice时并没有post出任何的用户信息,也就谈不上验证了,如何解决呢?请看下一篇:
增强Activex控件,暴露method方法,在javascript中操作activex控件并调用web service方法。