介绍一JS操纵word的一些知识

6 views
Skip to first unread message

星星

unread,
May 19, 2006, 12:40:06 AM5/19/06
to yuanhotel
面向对象的JavaScript编程(转) 面向对象的JavaScript编程
作者:liuruhong

Javascript对于做过Web程序的人不应该是陌生,初期是用来做一些简单的FORM验证,基本上是在玩弄一些技巧性的东西。IE
4.0引入了DHTML,同时为了对抗Netscape的Javascript,提出了自己的脚本语言JScript,除了遵循EMAC的标准之外,同时增加了许多扩展,如下要提到的OOP编程就是其中的一个,为了命且概念,我以下提到的Javascript都是Microsoft
Internet Explorer
4.0以上实现的JScript,对于Netscape,我没有做过太多的程序,所以一些的区别也就看出来。


Javascript不是一个支持面向对象的语言,更加算不上一个开发平台,但是Javascript提供了一个非常强大的基于prototype的面向对象调用功能,你可以在你自己需要的地方使用他们。因此,如何使用对象?本文尽可能从Javascript面向对象实现原理出发,解析清楚它的工作模型。在了解这些模型之后,你可以在自己的脚本库中编写一些实现代码,然后在其他地方调用。

Javascript的语法和C++很接近,不过在类实现中没有使用关键字Class,实现继承的时候也没有采用传统的Public或者Implement等等所谓的关键字来标示类的实现。这样的情况下,可能有就有人会问,如何编写Javascript的Class,如何实现继承。我开始也是百思不得其解,后来看了MSDN,才知道采用了prototype来实现,包括继承和重载,也可以通过这个关键字来实现。

Javascript的函数很奇怪,每个都是默认实现了Optional的,即参数都可以可选的,function
a(var1,var2,var3),在调用的过程中a(),a(value1),a(value1,value2)等等的调用都是正确的,至少在即使编译部分可以完整通过,至于其它,只是和函数的实现逻辑比较相关了。

以下就JS对于类的实现、继承、重载详细介绍其实现方式。

1。实现

Js类的实现就通过函数直接实现的,每个函数可以直接看成class,如下代码

function ClassTest1(){

...//implement code

}

var a=new ClassTest1

function ClassTest2(var1){

...//implement code

}

var b=new ClassTest("value")

对于类的属性,可以通过两种方式实现

1)this."<Property or
Method"的方式实现,在类声明函数中直接给出函数的实现,如
this.Add=new
function(strUserName,strPassword)这样的方式调用,编写的方式在Class
Function中调用。

2)通过ClassFunction.prototype.[FunctionName]=function(var1,var2...){//todo}这样的方式完成调用。

这两种方式从目标来看是一致的,按照我个人的观点来看,区别的只是在于实现方式,通过this.propertyName的方式来创建,Jscript自动创建了property或者method的入口,不过从程序的角度而言,还是使用prototype的关键字实现比较灵活。

另外Javascript也可以和我们C++中那种嵌套声明的方法来声明,C++实现的方法如下

Public Class ClassName:ParentClass{

Public DataType FunctionName(){

}

Public Class ClassName{

Public DataType FunctionName(){

}

}

}

在Javascript当中,当然不存在class这样的关键字了,所以实现起来有点戏剧性,不过仍然为一个非常巧妙的实现。

function className(){

//Property Implement

this.UserName="blue";

//Method Implement

this.Add=new function(){

}

//Sub Class Implement

function SubClassName(){

this.PropertyName="hi"

}

//sub class method implement

SubClassName.prototype.Change=function{

}

}

//Main Class Method Implement

className.prototype.Delete=function(){

}

如上的代码大致演示了Javascript类中属性和方法的实现,另外有一点比较困惑,整个class中都是public的,没有关键字private之类的可以控制某些方法是否隐藏,那么在我们编写代码实现的规范中,我看国外一些程序员都是使用_functionName这样子为函数命的方法来区分,但是在调用过程中实际还可以调用的。

实现了属性和方法,剩下的就是Event的实现了,我查找了许多资料,包括整个MSDN关于JScript的参考,都没有看到一个很好的模型关于事件实现的,后来参考了一些站点编写HTA(HTML
Component,有空我会写一些相关的文章)的实现,借助于比较扭曲(我个人认为)的方法可以大致的实现基于事件驱动的功能。大致的思路是这样子的:

1).将所有的事件定义成属性,只要简单的声明就可以

2).在需要触发事件的代码中判断事件属性是否是一个函数,如果是函数,直接执行函数代码,如果是字符串,那么执行字符串函数,通过eval(str)来执行。

3) .在类的实例当中注册事件函数。

为了简单说明如上的思路,采用timer这样简单的例子来表述如上的所提到的内容,如果只是为了简单的实现timer的功能,Javascript中setInterval函数就可以满足全部的要求,如下的代码只是用来说明Timer的工作原理。

//Class For Timer
function Timer(iInterval){
//if not set the timer interval ,then defalut set to 500ms
this.Interval=iInterval || 500;
this._handleInterval;
this.TimerEvent=null
function Start(){
if(this.Interval!=0){
this._handleInterval=setInterval("TimerCallBack()",this.Interval);
}
}
function Start(){
clearInterval(this._handleInterval);
}
function TimerCallBack(){
if (typeof this.TimerEvent=="function"){
this.TimerEvent();
}
else if(this.TimerEvent!=null && this.TimerEvent.length>0){
eval(this.TimerEvent);
}
}
}
//Code for Instance
var t=new Timer(3);

//------------------------------------//

//1.
t.TimerEvent=function(){
//todo
}

//2.
t.TimerEvent="alert(\"hello\")";

//3.

t.TimerEvent=tTimerCall;

//----------------------------------//
t.Start();
t.Stop();

function tTimerCall(){

}

实际工作代码是在TimerCallBack()上面实现,事件触发作为属性的方式来实现,在应用实例中,代码提供了三种方法去调用事件,不过在事件的回调当中,我还没有想到如何可以带参数,只有才各自的实现当中访问各自需要的属性才能够实现全部的要求。

2。继承。

刚采用了大篇幅的文字去介绍如何实现Javascript的各种实现,也就是从逻辑上完成了一个封装class的实现,从某种意义上来说,class的实现是真正脚本编程中使用最多的部分,不过如果只是要完成如上的功能,使用VBScript来编写更能更加清晰,毕竟VBscript提供了class关键字,同时提供了public
和private这两个关键字,可以清晰的将公共和私有对象分离,至于事件的实现,也可以采用类似Javascript实现的思路,只是对于函数的引用需要采用GetRef这个函数,具体的用法可以参考scripting
reference,MSDN里头也有详细的介绍,而Javascript强大至于在于如下要说的了,虽然具体的东西可能不多。

如上所言,我们已经完成了一个基本的类实现Timer,现在要做的是重新编写这个类,我们简单的只是想在这个类之中加入一个方法,提供当前的系统时间,方法的名称为getSystemDate,显然如果全部重新编写,那就失去了我这里说的意义了。先看看如下的实现。

function NewTimer(iInterval){

//call super

this.base=Timer;

this.base(iInterval);

}

NewTimer.prototype=new Timer;

NewTimer.prototype.getSystemDate=function(){

var dt=new Date();

return dt.getYear()+"-"+dt.getMonth()+"-"+dt.getDay();

}

上述代码实现了NewTimer类,从Timer继承,Javascript没有使用":"或者java的public那样类似的关键字,只是通过newclassname.prototype=new
baseclass这样的方法来完成,同时NewTimer实现了getSystemDate的方法,在NewTimer的初始化函数中,我使用了this.base=Timer,是为了引用父类的实现,不过在对于父类其他实现函数的调用,到现在我没有找到一个确定的方法,是否通过this.base.start()那样来调用还是其他的,如果有谁比较清楚的,麻烦告诉我,另外在netscape的站点上,我查到有一个特殊的"__proto__"的属性好像是对于父类的直接引用,不过具体的我也没有尝试过,在msdn中也没有看到对于__proto__的支持。

3。重载

或许这个是OOP编程中比较复杂的地方了,在Javascript的实现中有点无奈,也就是通过prototype的方式来完成的,不过因为我不清楚如何调用父类的实现函数,那么在重载中只能够重新编写所有的实现了,另外就是在实现中实例化一个父类,然后通过调用它来返回需要的东西。

Javascript中所有的对象都是从Object继承下来的,object提供了toString()的方法,也就是说如果调用alert(objInstance)这样的过程,实际上是调用了alert(objInstance.toString())的方法,如果没有编写实现,object默认的toString()都是"object
object"这样子的,在许多地方需要重载这个函数的,比如Timer,如果我们希望var
ins=new
Timer(5);alert(ins)调用得到的是interval的值5,那么就需要重新编写toString()方法了

Timer.prototype.toString=function(){ return this.Interval};

以上代码实现之后alert(ins)得到的就是5了。

长篇累牍的说了一堆废话,终于说玩了大致的想法,其实语言只是一个实现工具,重要的在于设计的思想,不妨可以考虑一下,在BITI内部开发一个OpenSource的Project,如果是基于javascript的模型来建立开发平台库,我希望有人可以参与。通过javascript建立一系列基于Web
UI的控件,目前我在开发过程中也是立足于上述的想法。另外,附上我去年写的类似HotMail的按钮那样的class源程序,暂时还没有使用Image
Preload,希望有人可以帮我修改一下,如果需要可以运行的版本,给我发送Email:liur...@263.net。另外有空我会写基于Javascript的组件编程和多媒体编程部分,再下来就是XML方面了,希望大家共同进步。
由{0}发表于 adu2008 ( 2006年03月16日, 10:46:53 上午 CST )

介绍一JS操纵word的一些知识(转)


创建word的js代码:
var myDocApp=null;
myDocApp =new ActiveXObject("word.Application");
myDocApp.Application.Visible = true;
var myDoc = myDocApp.Documents.Add();


myDocApp.Selection.ParagraphFormat.Alignment=1
myDocApp.Selection.Range.Bold=true;
myDocApp.Selection.Font.Size=22;
myDocApp.Selection.Text="请假申请单"
myDocApp.Selection.insertAfter("\n");
myDocApp.Selection.MoveRight(1,10);
myDocApp.Selection.TypeParagraph();
myDocApp.Selection.Font.Bold=false;
myDocApp.Selection.Font.Size=12;

var myTable0=myDoc.Tables.Add(myDocApp.Selection.Range,3,4);

myTable0.cell(1,1).Range.Text="请假人"
myTable0.cell(1,2).Range.Text=""

myTable0.cell(1,3).Range.Text="请假时间"
myTable0.cell(1,4).Range.Text="2006-2-10"


myTable0.cell(2,1).Range.Text="工号"
myTable0.cell(2,2).Range.Text="32412"


myTable0.cell(2,3).Range.Text="填表时间"
myTable0.cell(2,4).Range.Text="2006-2-9"


myTable0.cell(3,1).Range.Text="请假原因"
myTable0.cell(3,2).Range.Text="感冒"


myTable0.cell(3,3).Range.Text="处理方式"
myTable0.cell(3,4).Range.Text="病假"

var range=myDocApp.ActiveDocument.Content;
range.Collapse(0);
range.insertAfter("\n");
range=myDocApp.ActiveDocument.Content;
range.Collapse(0);


var myTable1=myDoc.Tables.Add(range,2,1);

myTable1.cell(1,1).Range.Text="正文"
var wdRowHeightExactly
myTable1.Rows(2).SetHeight ( 200, wdRowHeightExactly )
myTable1.cell(2,1).Range.Text="天气突然降温,着凉引发感冒!!"

var range=myDocApp.ActiveDocument.Content;
range.Collapse(0);
range.insertAfter("\n");
range=myDocApp.ActiveDocument.Content;
range.Collapse(0);

var myTable2=myDoc.Tables.Add(range,1,2);

myTable2.Columns(1).SetWidth(320,2);
myTable2.cell(1,1).Range.Text="
申请人签名" //空格勿删
// myTable2.cell(1,2).Range.Text="申请人的签名"
myTable2.cell(1,2).Select();
myDocApp.Selection.InlineShapes.AddPicture("E:\\user.gif");

var range=myDocApp.ActiveDocument.Content;
range.Collapse(0);
range.insertAfter("\n");
range=myDocApp.ActiveDocument.Content;
range.Collapse(0);


var myTable3=myDoc.Tables.Add(range,3,4);

myTable3.cell(1,1).Range.Text="组长意见"
myTable3.cell(1,2).Range.Text="同意"

myTable3.cell(1,3).Range.Text="签名"
myTable3.cell(1,4).Range.Text="组长的签名"


myTable3.cell(2,1).Range.Text="部门意见"
myTable3.cell(2,2).Range.Text="同意"


myTable3.cell(2,3).Range.Text="签名"
myTable3.cell(2,4).Range.Text="主任的签名"


myTable3.cell(3,1).Range.Text="厂领导意见"
myTable3.cell(3,2).Range.Text="同意"


myTable3.cell(3,3).Range.Text="签名"
myTable3.cell(3,4).Range.Text="厂领导签名"

try{
myDocApp.ActiveDocument.SaveAs("e:\\JaveToWord.doc");
}catch(exception){

alert("浏览器安全设置过高,保存文件到本地失败");
myDocApp.Documents.close();
myDocApp.Application.quit();
myDocApp=null;
window.close();
}
//myDocApp.Documents.close();
//myDocApp.Application.quit();
//myDocApp=null;
但是我如何在提交表单过程中把表单上的值传递到word的某一个区域中呢,谢谢!

给几个js写word的参考


/*
给几个js写word的参考:
this.Word.Selection.Font.Size = 16; //字体大小
this.Word.Selection.Font.Bold = true; //是否加粗
this.Word.Selection.ParagraphFormat.Alignment = 2;
//0左对齐,1居中,2右对齐,数字只能0-9,慢慢试吧
this.Word.Selection.InsertRowsBelow(1); //下面加入一行
this.Word.Selection.MoveRight(1); //光标右移
this.Word.Selection.TypeText(string); //只能写string
this.Word.Selection.MoveDown(); //光标下移
this.Word.Selection.EndKey(); //光标移动到末尾
this.Word.ActiveDocument.Sections(1).Headers(1).Range.InsertAfter(string);
//写页眉,结尾处写
this._LoadData = function () {
//替换函数,用于替换$strFld$类型的文本
 function replace( Range, strFld ) {
//[FindText], [MatchCase], [MatchWholeWord], [MatchWildcards],
[MatchSoundsLike], [MatchAllWordForms], [Forward], [Wrap], [Format],
[ReplaceWith], [Replace], [MatchKashida], [MatchDiacritics],
[MatchAlefHamza], [MatchControl]
 Range.Find.Execute( "$"+strFld+"$", true, false, false, false,
false, true, wdFindContinue, false, getElValue("l"+strFld) )
 }
//初始化Word控件
 this._InitWord = function ()
 {
 try{
 this.Word = new ActiveXObject("Word.Application");
 this.Word.visible = true;
 this.Doc = this.Word.Documents.Open( this.TemplatePath );
 this.Doc.Activate();
 this.Range = this.Doc.Range();
 return true
 } catch(e) {
 //TODO:
如果用户手动取消ActiveX的运行,则会留一WINWORD.EXE的进程。

//除非"设为可信站点,并在自定义级别里将第二项启用",则不会出现启用ActiveX的对话框。
 try {
 if ( this.Doc ) { this.Doc.Close(0) };
 if ( this.Word ) { this.Word.Quit() }
 }
 catch (e){}
 return false
 }
 }
*/

Reply all
Reply to author
Forward
0 new messages