发新话题
打印

[经验] 第三方Active X控件在J2EE系统中的应用

第三方Active X控件在J2EE系统中的应用

[摘要]
2 u& ?  r6 Q" j
# T# m3 c( ~9 ]2 }1 T在基于J2EE平台的信息系统中,具有丰富表现能力的Java Applet是界面层的一种重要形式。但Java API对打印的支持比较弱,打印输出复杂的单据和报表需要大量工作。本文介绍的系统通过引入一个ActiveX控件--Cell插件--来解决这个问题。该系统中,由Java Applet完成界面表现,由Cell插件完成打印输出,两者之间通过Sun公司的一套接口API互相通信。; M. I& j9 `4 R. @1 U7 }* }. {
3 E& ^7 y9 H9 V; V
2 @- A% b  j" B. `3 g
--------------------------------------------------------------------------------
2 u. c, F% q6 q# q  j, O$ B& k' m. I# n
一、Java Applet与Ocx控件的交互% Y6 d& P4 P8 V) h* p  W8 }8 A
1.1 从Java Applet访问Java Script方法和Ocx控件
7 N; ~% X( i1 }$ E4 I3 o7 _# V9 A1 h, {
Sun公司在JDK中提供了一套从Java Applet访问Java Script的API,由此可以实现Java Applet访问HTML页面中的DOM对象的机制。该API以一个Jar文件的形式提供:%JAVA_HOME%\jre\lib\jaws.jar,其中%JAVA_HOME%是你安装JDK的目录。将该jar文件加入到环境变量classpath中,就可以用它实现从Java Applet到Java Script的调用了。下面是一段调用Java Script中的方法的代码实例:) P6 V) V, Y- @0 A# r9 x" f
% _7 [* e( {3 J7 Q- d4 B
import netscape.javascript.*;6 m0 h( W. }" d) u% y7 ^

2 O4 _) f# K7 [" I$ F* Mimport java.applet.*;
# \2 [( L3 f; B$ V( B& c2 v4 M' u# P2 p  o* |2 D$ T
import java.awt.*;3 ?/ p8 P7 Q; y. A3 `( E
- q* U4 Q0 G' N
class MyApplet extends Applet {
/ S7 X! K4 P- r/ c2 x
7 U8 l/ ?% A6 `! x8 Bpublic void init() {& \$ R4 B$ C: e, N; B

8 H5 l- U, U: O' IJSObject win = JSObject.getWindow(this);: m: d+ E2 Q) Y3 h( H/ ~; |+ o, c0 ?

) f, Z# ?7 x3 E8 n3 G' `) RJSObject doc = (JSObject) win.getMember("document");
: _) \  G; ~0 a5 M. U# s0 h1 j6 |% n; e7 d
win.call("f", null);}}
0 T+ K: s$ W5 s. s
* i% d+ F$ f$ b" x0 R  u% l2 I在上面的代码中,win.call(“f”, null)调用了JavaScript中的方法f()。
# \. C$ G7 C' h3 _( x+ j: U   D9 d4 t* A) t* z, x$ ]
1.2 从JavaScript访问Java Applet
# S4 [7 c5 E7 O6 y9 B& p# M: p4 }3 X4 x! n0 u( P
当使用Java Plugin1.4.x运行Java Applet时,只需把Java Applet中的方法视为Java Plugin这个控件的方法,直接在Java Script中进行调用即可。下面用一个简单的例子进行说明:& M  }$ c5 v! W2 f/ {5 ?
/ u) x5 r3 }. q4 s
(1) 在载入Java Plugin的Object标签中,用参数ID指定一个名字:
2 M) g9 f5 c$ M, E, t/ u* p) R  C- n$ C) Y# I' X% N
             <OBJECT ID="MyPlunin" WIDTH=500 HEIGHT=120
( g2 e1 P2 W  Y* P" n6 `) U+ t' J$ h/ u, h% \5 X4 \& j- L
           CLASSID="CLSID:8AD9C840-044E-11d1-B3E9-00805F499D93">
& k4 _. C$ I( J, J" A  X0 y' y! {
' J! R' |& t5 c* H/ O4 _<PARAM NAME="code" value="MyApplet.class">...</OBJECT>(2) 在HTML页面上增加一个按钮,点击它时从Java Script调用Java Applet中的方法:* k, V/ Q( |! L% M  A
* g! Y" i9 \2 t( J
<input type="button" name="Button1" value="Start"onClick="calculate" language="JavaScript">(3) 假定你的Java Applet是MyApplet.java,它有一个public方法method1(),那么就可以用如下的Java Script代码直接调用该方法:
2 r3 L# E; ~/ p; ^* `, R" u
: i& A2 b& _- I<SCRIPT language="JavaScript">     function calculate() {                 document.. MyPlunin.method1()     }</SCRIPT>
' ^' m" e7 J% _" s3 |# b$ H& e& X- v! B" J- N, L3 k, H' O
. G* j& {' @4 n
, \, W' L( I9 V5 ?' K' e
二、Cell插件简介4 _- |! x6 X! q
华表的Cell插件是一个功能非常类似于Excel的、用于Web开发的ActiveX控件。它可以在Windows的浏览器中显示、编辑、打印表格。
8 N' S  c8 I$ H7 b' S ! A+ \* P! W1 x- v3 H! ]

- t3 U7 a3 |5 a" T7 _& e1 ?三、系统实现6 ~% p) p- C# G6 k1 `
1.1  系统架构% q& f. I2 F0 S. x
+ j& ^$ x9 ?5 \& z- `: b
0 z, `& a8 G6 s+ }" H

/ i1 L# i+ W1 v' k图一是系统的配置示意图。由图可见,这是一个典型的三层应用系统。在本系统中,Java Applet和Cell插件部署在Web Server上,在运行时,它们被下载到客户端,运行在浏览器中。
! ?/ [7 H  z0 |, E' O. X1 l
' Y5 V- J/ @0 O5 a6 @: K6 g7 ]* U: b0 ~+ o
; _1 P8 M5 g, _( {9 X
图二是系统的运行示意图。由图可见,运行在客户机上的Java Applet通过Web Server上的Servlet访问应用服务器上的EJB,与后台交互。Java Applet作为表示层,在客户机上显示界面。2 s& Z  r, V" {' q- `" E( h2 |

9 C8 y  S/ e# h当需要打印输出时,Java Applet将数据和显示格式设置到华表插件中,并调用华表插件的打印预览和打印方法,完成打印功能。# W0 C7 W% ?! `0 S

- z- N0 q* Q: h- l( Q" l9 w' Q0 V9 l1.2  用Cell插件实现Java界面的打印1 F$ X, h* N5 X6 M+ Q

. ?# Y, u6 |; ^% o0 Y2 q+ P(1) 在HTML页面上嵌入华表的Cell插件
, Z, _* ^4 B" b8 O0 A$ [% Y
5 O' g3 B. E, D- Y* c& N为了在Applet界面中调用华表的Cell插件,我们首先在HTML页面上隐藏了一个Cell插件:
) J9 b& A+ B9 C6 L/ l  g- h4 T4 P, h! n" W- {; J3 n) Q+ P5 c
<OBJECT classid=clsid:3F166327-8030-4881-8BD2-EA25350E574A 4 s9 K& ?" H# ^1 Q; {
" U6 W6 P6 @- R9 b' p
      id=DCellWeb1   style="HEIGHT: 0px; WIDTH: 0px">: [( R5 }5 p% ~; g
) j" W" k% P# u4 |
      <PARAM NAME="_Version" VALUE="65536">
% [4 N- z3 K+ d: r
3 q' h! [3 S  P0 ~      <PARAM NAME="_ExtentX" VALUE="14902">
4 n2 F. J+ `, j% h; _# l2 N# i# W# L; `4 \$ N) z
      <PARAM NAME="_ExtentY" VALUE="6075">
! g. \% l' M2 v/ c9 m% w: c9 N
      <PARAM NAME="_StockProps" VALUE="0">! O! i: @7 }/ c: Q0 H
4 M* i  x8 }! H
</OBJECT>
& `3 l* B% I5 ?
9 }9 j* u0 l( j% b8 E+ _通过style="HEIGHT: 0px; WIDTH: 0px"指定Cell插件的高度和宽度都为0,从而达到隐藏Cell插件的目的。
( r+ P, Z+ a7 D& Q
# p4 p7 e: \3 l. X+ j4 k) f0 l(2) 在Applet中提供两个调用接口方法
1 ]# F4 n+ F+ R: M) g7 I7 h7 @' K2 t, ]! ]6 a& J2 Y6 J
下面是一个Applet的代码实例,其中提供了callCellMethod()和callJavaScriptMethod()两个接口方法,分别可用来调用Cell插件的方法和JavaScript的方法:: q4 Y6 I6 @6 ?/ F1 R0 e
. g, z1 @9 Z+ d0 H& N$ A
public class MyApplet extends javax.swing.JApplet {4 H* f6 Y3 @& ~
! }, O3 g8 r: P% j  g' [7 s9 s
private JSObject win = null;
2 a- u% j' P4 V8 }. Q! I* ?7 {: ?( C" U, N- N; C1 X$ c$ Q
private JSObject cell = null;
0 x+ X( [4 u! S* d% t# }! D. ]* {! I; \* F$ g, p
public Object callCellMethod(String name, Object[] params) {
9 j; N5 A7 K( o
( T7 b4 K/ {* ?return getCell().call(name, params);}) ?$ }1 ^/ i& k) N1 Z+ G
6 D" ]) Q3 o# s% T- b1 ^% a7 x
public Object callJavaScript(String name, Object[] params) {
8 ^- Y2 E1 e) p  k9 P/ Y8 m/ o% Q7 n
return getJSwin().call(name, params);}
+ a( H! @* \: l8 ~4 V  [7 l- @& S% Q! @1 d
private JSObject getCell() {
* ^  w& b% i3 o# G7 h; o
+ O6 T0 ]  Q* U% A9 Yif (cell == null) {
' a( J& l, V) k! e" u* [% l. Q* ^9 y2 Q3 q0 h
try {
, U/ m( h% [0 j4 u7 l6 N& L$ l' c- t! f* o! [% G2 [
JSObject doc = (JSObject)getJSwin().getMember("document");+ X1 {+ E: C) `3 `% O
. \! w6 Z3 j! J) e
JSObject all = (JSObject)doc.getMember("all");* R) C9 v  x- Y! P& {! [7 L9 _
! {! H% \- y9 d. m
cell = (JSObject)all.call("item", new Object[]{"DCellWeb1"});}
$ _+ W+ B4 f  a
! ]* D- l# x! f, e6 h; V5 \catch (Exception e) {
3 B8 `4 W6 j+ J+ D* h  n) K, D) o! p
% `* R4 A% w& a* j. _; n" e+ ye.printStackTrace();} }/ R* k) w  E: }- L* `7 E0 ^/ \

, v+ ?" K) k' r' Y! K" t) A8 jreturn cell;}" f4 s& B. ?/ I3 Y" J
4 `, p9 J$ D6 [7 G. L& ~
private netscape.javascript.JSObject getJSwin() {3 t& _7 }6 A& I' j/ w, S6 n

6 ]" o6 @; L. }# V- I# |* n/ L5 ^8 Cif (win == null) {
" b6 }3 o$ [- b: ?; D) e% M! ?( }: [9 [8 J7 t6 }6 K
win = netscape.javascript.JSObject.getWindow(this);}
! J6 Z) j. M( \$ z+ @7 W9 P. \" a& t. {, T2 I& `9 Q) _9 J
return win;}}
# s( R- l; g4 |
. P0 |7 S0 s0 O* ]- R; G通过getCell()这个方法,可以在Java Applet中直接获得用JSObject表示的Cell插件,从而可以直接调用它的方法。例如,在Java Applet中向Cell插件的一个单元格写入数据,可以如下调用:6 ]* V* ~* |' Q/ ]' P5 x/ _0 c

" F: U) i6 m: |/ M+ k5 Q$ EInteger row = new Integer(1);8 ^" E, Q! L3 H+ q- o
- ~% z: j4 Z) U
Integer column = new Integer(1);
$ ]& L& Z+ V  z9 L) F* _, t% A4 ~; J- ?1 ]% k9 n& V
Integer page = new Integer(0);
6 i( i0 U0 d9 v- f: T1 X  a# j% x& ?7 [$ U1 a2 _
callCellMethod("SetCellString", new Object[]{column, row, page, “str”});" t" O( @( P8 y- F

7 I4 ]# y+ x8 Z# ?其中SetCellString是Cell插件提供的接口方法。这样就实现了从Java Applet到华表的Cell插件的调用。
, n& d% z3 A) G+ u) m # z" A+ ~' d* V1 z! I

; W5 Y+ k- i1 _6 O" B, q五、结论9 h5 [# ?8 v" @, I( D. ?0 X7 [
在这个应用系统中,我们只利用Cell插件的打印预览和打印两项功能,不用它做屏幕显示。所有打印格式和数据都在Java Applet中准备好,按单元格向Cell插件设置格式和数据,由Cell插件完成分页和打印功能。3 |. H3 F- o, ^7 e0 o& N  G
6 K$ p5 p8 X+ v. A! f, C$ I. |
这是一种表现与数据分离的方式:Java Applet中只组织打印数据,所有打印的表现工作交给Cell插件完成,因此能够大大降低工作量。; G5 G) C( x/ M: i  M

! K9 m  v/ T9 vCell插件除打印功能外,还具有输入、显示、编辑、图表等非常强大的功能,可以制作出非常复杂的报表。利用Cell插件,还可以将数据导出为Excel或PDF等格式的文件。% y; k. U# O6 _0 K; D1 T0 J+ C6 L
9 i+ q& e1 `; [, B& [' A- U" ~

/ L9 A% G- x  h+ V* O# r) H六、参考文献1 @$ W- G6 `) i! v6 E
1 Cell插件文档:http://www.cellsoft.cc/csdn5 z  M9 k: p+ ~# I2 X

! g4 F, k# N  M( f. R2 Java Plugin 文档:http://java.sun.com/j2se/1.4.1/docs/guide/plugin/3 Z6 T) a2 G4 L; y
- Q$ o% l. I1 @1 S  @8 U
1 @, _/ K! }! ]% t/ i
赵继江
/ p$ I7 Y+ [* k% q: c! l5 T; e! {7 R" X
2003年1月

TOP

发新话题