但是,随着Internet
逐渐为大家熟悉和逐渐普及,越来越多的功能被移植到“开放空间”,以实现更好的可视性和更有效的通讯。比如说,一个人也许要问:“我可以登录到Internet /
Intranet,填写一张休假申请表,然后以公司标准模板样式将它作为Word 文档发送给我的经理吗?”答案是肯定的,下面会为你演示如何实现。
关于这个应用程序 我们的应用程序有一个样本表格,由访问web 站点的用户填写。一旦提交,ASP文件收集其中信息,使用web
服务器上存放的预先定义的模板,以其内容创建一个Word
文档。然后显示一个链接,允许用户查看或者下载这个文档。
我们创建一个Visual Basic COM 组件(ActiveX DLL),
通过ASP应用程序调用它,给它传递必要的参数。组件从本质上是使用Microsoft Word 对象库,创建一个对将要传递参数的 Word
文档的引用。所有这些都是在服务器上完成的,因为这种方法有许多优势。
其中最重要的是在程序内运行的since.dll
(与网络服务器在同样的内存中),它们比程序外运行的(如CGI或Perl
脚本)运行更快,使用的资源更少,后者在运行中每次被调用时,都将创建自己本身的实例(如复制)作为单独的程序,因此要用掉大量的服务器内存。这还意味着为了使程序外组件在服务器上运行(关键字:ASPAllowOutOfProcComponents),你不需要修改Metabase
(一个存储Internet信息服务器配置设置的结构,与Windows
注册相同,但是使用较少的磁盘空间)。
另一方面,这种方法最明显的缺点也许是因为它与网络服务器在同样的内存空间中运行,任何DLL的问题都有可能使服务器出故障。因此,在开发和执行程序内应用程序时需要十分小心。
程序要求和优点
完成本文所说的功能,需要具备以下条件: ●
Visual Basic 5 或 6 ● 具备IIS 4的NT服务器 或 工作站,或者有PWS 的任何 Windows 9.x ● MS Word
97 ( Office 97 套装的一部分)
本例还可以和MS Word
2000一起执行,但是会有一些问题,在文章最后要提到。其它额外的软件是不必要的,只需要保证默认站点http://localhost/ 是有效的(点击这个超
踊岚涯愦礁鋈说膚eb 服务器或Windows NT
的主页)。 我们将把创建的所有文档都存储在C:\Inetpub\scripts\documents 文件夹中,
所以一旦文档被创建之后,我们提供到它的链接是很容易的(可以根据需要修改)。一定要创建这个路径,否则我们的例子就不能工作。所有其它的文件都位于我们的脚本路径 (
C:\Inetpub\scripts )。我们的dll
将尽可能地灵活,使任何模板的修改都只需要最少的代码修改。
更深一层的技术
要设计的模板可以基于一个公司希望在他们的文档出现的内容:登录、适当的页眉和页脚信息、基本文本等等。另外文档创建之后,我们希望在其中看到用户特殊信息的地方还要加入标记(这就使这个应用程序是动态的)。在我们回顾代码时还会仔细看这些部分。我们的.dll
将包含一个称为GenerateDocument 的函数(在类文件内部),它要求向它传递4个参数,分别是: ● 一个为所有标记用的分界字符串(来自文本模板)
● 一个为所有相应值用的分界字符串(来自 web浏览器上用户填充的表格) ● 模板在服务器上的位置 ●
生成的文档在服务器上被存储的位置
现在我们可以往下进行了。
组合在一起 文档模板
首先创建一个word
模板的样本,假设它就是我们公司的标准文档模板。我们要为这个例子获取职员的信息,我们希望文档中包含以下的特定信息:名字、地址、Email
Id。现在基于这些信息创建模板,一定要在文档中将要显示用户信息的地方包含适当的标记(如. < Name >, < Address
>)。
将文件命名为EmployeeTemplate.dot(记住,在Save As
对话框的文件类型列表中选择文档模板,并将其存入C:\Inetpub\Scripts\Templates\。看看可下载材料部分包含的文档模板样本,以便对它有个更好的理解。
COM组件 现在用Visual Basic创建COM组件,按照以下的步骤: ● 启动
Visual Basic, 选择 ActiveX DLL 作为工程文件类型。 ● 将类名改为DocumentObject, 工程文件名改为
MyDocumen(这是我们在ASP页中创建COM组件的一个例示时要使用的信息) ● 接着,点击工程文件菜单选项,到 References。 ●
向下滚动直到看见 "Microsoft Word n.0 Object Library " (n
是一个识别服务器上安装的word对象库版本的数字).选中这个选项,点击click
OK。
请参阅本文结尾处可下载文件中的类模块代码。GenerateDocument()函数要用到从ASP文件向它传递的4个参数。 它返回一个字符串类型,在后面可以看到: Option
Explicit Declare a New word application Object Dim wdApp As New
Word.Application Public Function GenerateDocument(sTags, sValues,
sSourcePath, sDestPath) _ As String On Error GoTo ErrHandler Dim
arrTags() As String, arrValues() As String, iLoop As
Integer
此函数执行的第一个任务是从指定的源路径(作为参数从ASP文件传递过来)打开模板文件。基于在服务器上创建的模板,引用一个新的Word
文档: wdApp.Documents.Open sSourcePath
然后,将从HTML表单中获取的所有标记,用Split
函数放入arrTags数列中。逗号是一个分界符,在ASP文件中分隔开标记的值: arrTags = Split(sTags, ",
")
我们将相应的用户输入值存入arrValues数列。pipe 字符( | ) 是分界符,来分隔开这些值:arrValues =
Split(sValues, " | ") 代码在arrTags 中循环 ,用查找和代替操作(用应用程序脚本的Visual
Basic)从标记数列中找到标记,在创建的Word文档中,用arrValues 数列中的相应值代替它们:
For iLoop = 0 To
UBound(arrTags) wdApp.ActiveDocument.Content.Find.Execute arrTags(iLoop), ,
True, , _ , , , , , arrValues(iLoop), 2 Next
iLoop
你看到的一串逗号是Find-Execute 方法的不同属性,我们没有设置。我们只对 MatchWholeWord,
ReplaceWith和ReplaceAll(用数字常量2代表)的设置选择感兴趣。然后,我们将文档存入指定的目的路径和文件名中,退出和释放之前关闭这个word文档对象:
wdApp.ActiveDocument.SaveAs
sDestPath wdApp.ActiveDocument.Close wdApp.Quit Set wdApp =
Nothing 退出函数之前,返回一个Success 标志: GenerateDocument = "Success" Exit
Function 这是一个错误处理程序。如果在上面的应用程序执行中遇到错误的话,它返回一个错误信息。
ErrHandler: Quit and release the word document
object wdApp.Quit Set wdApp = Nothing Build the Error Message, and pass
it back Dim ErrMsg As String ErrMsg = "Error Number: " & Err.Number
& "< BR >< BR >" ErrMsg = ErrMsg & "Error Source: " &
Err.Source & "< BR >< BR >" ErrMsg = ErrMsg & "Error
Description: " & Err.Description & "< BR >< BR
>" GenerateDocument = ErrMsg Exit Function End Function Private
Sub Class_Terminate() Release the reference Set wdApp = Nothing End Sub
在Visual Basic中,保存应用程序(保留类和工程文件名),编译,看是否产生了什么错误。然后,打开File 菜单, 点击Make
MyDocument.dll。保留它的名字,在工程文件所在的文件夹中保存它。
然后,在web 服务器上注册dll,如下: ● 将
MyDocument.dll 复制到windows\system 或 winnt\system32路径(取决于使用的操作系统). ●
在命令提示符下执行以下命令 C:\winnt\system32 >regsvr32 MyDocument.dll ●
你将看到一个成功的信息:DllRegisterServer in MyDocument.dll
。 上面完成了这个应用程序的主要部分。现在进入下一步。
HTML 页面
现在需要创建HTML页面(
EmployeeForm.html ),用户将在其中输入填充到新Word 文档中的值。下面是我们使用的HTML页样本: < HTML
> < TITLE > Employee Registration Page < /TITLE > < BODY
BGCOLOR=#ECECEC > < CENTER >< FONT FACE=arial SIZE=-1 >
< FONT SIZE=5 > Employee Registration Page < /FONT > < HR
ALIGN=center COLOR=black >< BR > Please complete your details as per
the Registration Form...< BR >< BR > < TABLE CELLSPACING=1
CELLPADDING=5 BGCOLOR="#000000" BORDER=0 ALIGN=center > < FORM
ACTION=CustomDoc.asp METHOD=post > < TR > < TD BGCOLOR=#00BCA8
COLSPAN=2 ALIGN=center > < B > < FONT FACE=arial SIZE=-1
COLOR=black > Employee Details < /TD > < /TR > < TR
> < TD BGCOLOR=#C4C2C2 > < B >< FONT FACE=arial SIZE=-1
COLOR=black >Your Name: < /TD > < TD BGCOLOR=#E3E1E1 >
< INPUT TYPE=Text NAME="Name" SIZE=20 MAXLENGTH=25 > < /TD > <
/TR > < TR > < TD BGCOLOR=#C4C2C2 > < B >< FONT
FACE=arial SIZE=-1 COLOR=black >Address: < /TD > < TD
BGCOLOR=#E3E1E1 > < INPUT TYPE=Text NAME="Address" SIZE=40 MAXLENGTH=40
> < /TD > < /TR > < TR > < TD BGCOLOR=#C4C2C2
> < B >< FONT FACE=arial SIZE=-1 COLOR=black >City, State:
< /TD > < TD BGCOLOR=#E3E1E1 > < INPUT TYPE=Text NAME="City"
SIZE=20 MAXLENGTH=20> < INPUT TYPE=Text NAME="State" SIZE=20
MAXLENGTH=20 > < /TD > < /TR > < TR > < TD
BGCOLOR=#C4C2C2 > < B >< FONT FACE=arial SIZE=-1 COLOR=black
>Zip, Country: < /TD > < TD BGCOLOR=#E3E1E1 > < INPUT
TYPE=Text NAME="Zip" SIZE=20 MAXLENGTH=20 > < INPUT TYPE=Text
NAME="Country" SIZE=20 MAXLENGTH=20 > < /TD > < /TR > < TR
> < TD BGCOLOR=#C4C2C2 > < B >< FONT FACE=arial SIZE=-1
COLOR=black >Email: < /TD > < TD BGCOLOR=#E3E1E1 > < INPUT
TYPE=Text NAME="Email" SIZE=40 MAXLENGTH=40> < /TD > < /TR >
< TR > < TD BGCOLOR=#00BCA8 COLSPAN=2 > < INPUT
TYPE=Submit VALUE="Save and Generate Profile Document" > < INPUT
TYPE=Reset VALUE="Clear Fields" > < /TD > < /TR > <
/FORM > < /TABLE > < /BODY >< /HTML
> 将文件存入C:\Inetpub\scripts\ 中,要确定脚本路径在个人Web服务器或IIS中有读取并执行权限。

ASP页面 ASP页( CustomDoc.asp )
实际完成以下任务:取得用户输入、用COM组件创建Word 文档、 将它递交回用户。下面是带注释的代码: < % Dim sTags,
sValues, sDestPath, sSourcePath, resValue Get all the User Input values from
the Form sName = Request("Name") sAddress = Request("Address") sCity =
Request("City") sState = Request("State") sZip =
Request("Zip") sCountry = Request("Country") sEmail =
Request("Email") sDate = Now() Create a list of all the tags as defined in
the Word Template by You sTags = "< Name >, < Address >, <
City >, < State >, < Zip >, < Country >, " & _ "<
Email >, < Date >" Gather up all the User Input values into one
delimited string sValues = sName & " | " & sAddress & " | " &
sCity & " | " & sState & _ " | " & sZip & " | " &
sCountry & " | " & sEmail & " | " &
sDate
完成之后,需要识别源文件(Template) 和目标文件(Document)的位置。APPL_PHYSICAL_PATH
返回CustomDoc.asp 文件所在的路径。我们将文档文件夹和文件名附加在一起,这是用户负空间的名字。
sSourcePath =
Request.ServerVariables("APPL_PHYSICAL_PATH") & _ "Templates\" &
"EmployeeTemplate.dot" sDestPath =
Request.ServerVariables("APPL_PHYSICAL_PATH") & _ "Documents\" &
Replace(sName, " ","") & ".doc"
现在完成了常见MyDocument对象的例示和调用GenerateDocument.doc,在返回值的基础上进行适当的操作。 Set
myDocObj = Server.CreateObject("MyDocument.DocumentObject") Call the
GenerateDocument function while passing the required Parameters retValue =
myDocObj.GenerateDocument(sTags, sValues, sSourcePath, _ sDestPath) Take
appropriate action based on the returned value If retValue = "Success"
Then Msg = "Successfully generated your Document : " & Replace(sName,
_ " ", "") & ".doc" Response.Write("< font face=arial size=-1
color=Green >< br >" & Msg) Response.Write("< br >< br
>< a href=Documents/" & _ Replace(sName, " ","") & ".doc" &
" >Here it is!< /a >") Else Response.Write("< font face=arial
size=-1 color=Red >< br >" & retValue) End If % >
将文件存入C:\Inetpub\scripts\。就行了。现在在浏览器中键入 http://localhost/scripts/EmployeeForm.html,执行应用程序,输入所有的域值,点击 Save
and Generate Profile Document。现在可以看到我们的方法是多么有效和美观了。
对于Office 2000
的问题
如果你的机器安装了Word 2000,并且用Microsoft word 9.0 对象库创建dll
的话,就会遇到一些问题。组件本身好象工作得绝对良好,没有任何错误,但是从ASP页调用会操作超时,或产生一个ActiveX
不能创建对象的错误。这也许是Office
2k设计上的特色,或者也许是一个错误(Bug)。下面解释一下为什么会发生这些问题。大致来说,这是因为安全信用不能在所有的例示子对象中持续。当调用一个.asp
页时它作为IUSR 帐号(web 服务器上的默认interne[1] [2] 下一页 |