发新话题
打印

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

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

[摘要]$ ?' ?( b, |. }% ~3 L1 O
# C+ T% [9 f9 x$ j9 [3 u
在基于J2EE平台的信息系统中,具有丰富表现能力的Java Applet是界面层的一种重要形式。但Java API对打印的支持比较弱,打印输出复杂的单据和报表需要大量工作。本文介绍的系统通过引入一个ActiveX控件--Cell插件--来解决这个问题。该系统中,由Java Applet完成界面表现,由Cell插件完成打印输出,两者之间通过Sun公司的一套接口API互相通信。. i8 ?  k. G' x8 b: h2 L; r
$ k( `* d9 O  t" I3 L
) e6 ]2 S  k  r0 ~7 ]
--------------------------------------------------------------------------------! C7 u3 `: |# ]3 V( r

( J9 d& b% w/ z8 s! \一、Java Applet与Ocx控件的交互
, f6 X  e. J" c3 C, ~) o' U1.1 从Java Applet访问Java Script方法和Ocx控件4 h5 H% Q4 [) i. I

6 `9 R1 h+ ]' |* E" `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中的方法的代码实例:
" W* y8 Q. m% }! P/ z5 C; d9 P& J) c! E" G. C1 N
import netscape.javascript.*;
1 Q% s$ h- ?3 Q7 d8 |% e6 E8 n5 Q  y+ k0 \/ Q' D3 F
import java.applet.*;5 Q  \4 T0 H  z# I7 F

4 R( T3 X  H/ ]import java.awt.*;
6 m9 Q* x5 C) L0 j6 k& D5 b2 O' U8 {0 z( B
class MyApplet extends Applet {3 V' |4 ^7 p5 v* R; [

& |# J6 S4 q0 g* I+ epublic void init() {
% j3 w% P( x1 z5 J+ }. n- @2 P6 [6 i# |% T, }+ c: }
JSObject win = JSObject.getWindow(this);
% c- {4 G* o0 r$ S. Q3 D$ j" L  z' M" @" T$ P  O$ x, S8 s3 _
JSObject doc = (JSObject) win.getMember("document");
7 I* v3 C$ w2 H5 u' q4 e3 V4 @- B& F! [2 B; s! A7 T
win.call("f", null);}}
5 q" u5 X) z7 }, D
' H7 F5 I) Y; j0 {+ ]在上面的代码中,win.call(“f”, null)调用了JavaScript中的方法f()。, M! n1 [# h$ d3 W5 `! h+ s

8 h# f8 N1 T0 m9 M1.2 从JavaScript访问Java Applet
1 j1 i: }2 Y9 T8 X, @$ v; y. \* Q
- D; b5 h, p" Y" n  A0 \当使用Java Plugin1.4.x运行Java Applet时,只需把Java Applet中的方法视为Java Plugin这个控件的方法,直接在Java Script中进行调用即可。下面用一个简单的例子进行说明:
8 l& a3 q- t3 O( l. u0 g* [' H/ b& Y! M! p* P4 o
(1) 在载入Java Plugin的Object标签中,用参数ID指定一个名字:. X' m+ h0 w1 ?" J7 z7 T

. }0 _4 d, m$ j- F: K             <OBJECT ID="MyPlunin" WIDTH=500 HEIGHT=120
/ J  G6 Y/ C4 H3 X4 ?
1 ?9 o* Z% `0 d7 b1 c, B           CLASSID="CLSID:8AD9C840-044E-11d1-B3E9-00805F499D93">
  k0 P, ]5 l% w& d0 r- z$ U
. I+ e- G3 o' _) T1 Z' o<PARAM NAME="code" value="MyApplet.class">...</OBJECT>(2) 在HTML页面上增加一个按钮,点击它时从Java Script调用Java Applet中的方法:
9 }0 ?# {5 s* m* ^7 \
( |  s, n- Q9 _+ }' n! Z" j- o5 g<input type="button" name="Button1" value="Start"onClick="calculate" language="JavaScript">(3) 假定你的Java Applet是MyApplet.java,它有一个public方法method1(),那么就可以用如下的Java Script代码直接调用该方法:
3 f8 ~$ ^1 x: q' z# {0 ~' P1 x2 O$ X3 x$ b+ s
<SCRIPT language="JavaScript">     function calculate() {                 document.. MyPlunin.method1()     }</SCRIPT>. k: Q$ @- s; a" c, x# D' }

8 p0 x( H9 p; D5 y2 v6 _0 k1 } ! x3 u, q' Z8 J

5 D. B/ i6 ?& {二、Cell插件简介  e  l7 X. E* b! F: ^  a# x
华表的Cell插件是一个功能非常类似于Excel的、用于Web开发的ActiveX控件。它可以在Windows的浏览器中显示、编辑、打印表格。( W8 b( u5 f& e- R5 {( D3 Y; s
5 v8 m& B4 S7 T  C
8 q/ h6 n: U, r" A" U' U
三、系统实现
1 A. i% V7 h" f1.1  系统架构/ ^* d8 d% M3 ]& }+ E9 ]

1 ?3 j8 ?, t) g: G' |) x# t# U0 d6 f3 H6 \

9 e: c7 o2 o/ C, u( T# r. c图一是系统的配置示意图。由图可见,这是一个典型的三层应用系统。在本系统中,Java Applet和Cell插件部署在Web Server上,在运行时,它们被下载到客户端,运行在浏览器中。
% g& w7 n& [* y, G* }2 w
% s9 ~8 ?* m5 O' K) Z0 _. h! o# N- a. Z
4 R, Z5 r) c6 K; x# G
图二是系统的运行示意图。由图可见,运行在客户机上的Java Applet通过Web Server上的Servlet访问应用服务器上的EJB,与后台交互。Java Applet作为表示层,在客户机上显示界面。+ S' p) P0 A5 {3 s& B
' {& k  S0 B/ `
当需要打印输出时,Java Applet将数据和显示格式设置到华表插件中,并调用华表插件的打印预览和打印方法,完成打印功能。, {  I2 B4 x, ^/ N  R. k; i

5 k0 T+ r$ B& m! P$ A' i1.2  用Cell插件实现Java界面的打印  K$ |% J3 r# n

6 G2 {1 ]7 U1 t0 x7 g0 r0 ~6 M1 H(1) 在HTML页面上嵌入华表的Cell插件
- @0 w5 `$ Z& F" M/ z( C; I
, ]4 T# H  A8 w  P% }为了在Applet界面中调用华表的Cell插件,我们首先在HTML页面上隐藏了一个Cell插件:5 w8 S/ F, w; S7 i& w
2 |" r6 w0 K7 P2 ^
<OBJECT classid=clsid:3F166327-8030-4881-8BD2-EA25350E574A ! ]/ S, m: J9 M, ?; u2 _1 [
* I" X  V2 N4 u# h' w- M! u% y
      id=DCellWeb1   style="HEIGHT: 0px; WIDTH: 0px">
2 [! s/ `2 B$ t. ?) V& W) A- n' V) |0 b; a1 A# j! Y$ G0 u+ B
      <PARAM NAME="_Version" VALUE="65536">- A; Y3 G. a! Q

; g4 {. ^- U. n/ P& X5 ~$ p% q" @      <PARAM NAME="_ExtentX" VALUE="14902">
, Y5 z% v: M' x* o. u
+ |- R! }) y  w5 g: I( x      <PARAM NAME="_ExtentY" VALUE="6075">
' }5 C- X- G5 J- U
" n' v8 k  X  X9 ^% S      <PARAM NAME="_StockProps" VALUE="0">
4 {0 |) {1 j0 a1 n& s
! {! J  K- `5 \! G$ N7 r% R</OBJECT>" V% F" K1 I  K$ m6 `

8 P" H8 V; c$ ?" B- I# d: e4 K通过style="HEIGHT: 0px; WIDTH: 0px"指定Cell插件的高度和宽度都为0,从而达到隐藏Cell插件的目的。' ~0 j7 c5 ?4 D
; q5 {2 h! b  T
(2) 在Applet中提供两个调用接口方法% m* P! x6 g2 q( v

4 [# ?8 C5 W% Q( y6 J下面是一个Applet的代码实例,其中提供了callCellMethod()和callJavaScriptMethod()两个接口方法,分别可用来调用Cell插件的方法和JavaScript的方法:2 T: ^4 X1 n0 T! r1 p
7 Z! n0 I! r' `$ {4 K1 H% a- R3 o
public class MyApplet extends javax.swing.JApplet {" Y, \" o9 j$ m# D$ |) H
# g6 g8 N6 m6 G7 z9 v
private JSObject win = null;% k) u! j* P9 s5 h0 u. E

% H. P6 K  c1 o- F0 D1 G3 ^' Gprivate JSObject cell = null;1 R) N6 K, N& p. |

( p- u9 v( n( ^# jpublic Object callCellMethod(String name, Object[] params) {3 M( q% f+ @  J( x

: z8 O" R/ b! e6 ?9 xreturn getCell().call(name, params);}
% t: k& r# u1 c) v* D/ s1 B6 t) h- q$ b( x! W+ d# M; x: C, T* [" ]
public Object callJavaScript(String name, Object[] params) {  l# z6 k" z" X, e% `

: ]  l0 t2 |9 t5 A) Vreturn getJSwin().call(name, params);}8 \0 J, d$ g$ B

2 @5 g" j& i/ Rprivate JSObject getCell() {
; l' m' ~: U+ P- A! s9 d; X0 S; }" `1 R5 w
if (cell == null) {
; V$ \  z- a6 d! e7 _! ^, {* X: Q5 g5 O% ^+ e1 X
try {5 ~7 _7 G" }4 d% E
( I& A# X: \5 m( K! R7 U8 W
JSObject doc = (JSObject)getJSwin().getMember("document");  P+ ]5 M" b. F; l' X
& j* o0 P8 x0 k& g! |6 k" t) u
JSObject all = (JSObject)doc.getMember("all");# l% h/ g$ D9 r) x6 i
: P- B$ z' V7 r, Z
cell = (JSObject)all.call("item", new Object[]{"DCellWeb1"});}9 K- B. V) k+ T" p
, q: n5 _- b9 K
catch (Exception e) {
( }. D% Q/ `+ s3 l. ]! I* C2 C  L
" A) s  S. P4 i# S( o+ fe.printStackTrace();} }
/ \3 d0 ~4 j; h, _4 ]
$ _5 q7 s6 S$ Q8 ?$ U0 dreturn cell;}
6 n1 f- n- c6 u! ~9 W% S  N% Y' |
private netscape.javascript.JSObject getJSwin() {
7 W0 x& V2 R9 u
) f$ z5 l5 _' E+ B5 H0 sif (win == null) {0 I' D$ i. @$ \  v5 W6 h
3 {7 Y& {1 C* O1 x* K1 Y' x
win = netscape.javascript.JSObject.getWindow(this);}: B2 I! e6 _8 }( W7 J! [

1 x$ l' a( E; m; E2 Z) rreturn win;}}7 ?$ @% ?- T9 `3 J$ E# _: j
% X4 R, o0 m( A( g
通过getCell()这个方法,可以在Java Applet中直接获得用JSObject表示的Cell插件,从而可以直接调用它的方法。例如,在Java Applet中向Cell插件的一个单元格写入数据,可以如下调用:
% n7 Z( g( \0 g- n6 F, j6 l$ I- s6 f& W+ u) f$ z
Integer row = new Integer(1);
0 a$ r# x% b: i! c" `( |
$ w7 ?$ K9 N" PInteger column = new Integer(1);8 f) r1 Y, r* r

- s- e: p+ x3 ]' k9 X' o: q3 UInteger page = new Integer(0);
4 g. m% `6 o* R  k; H6 P. D" p4 u5 m, q9 n
callCellMethod("SetCellString", new Object[]{column, row, page, “str”});
& h" t* N  E1 r& V" \! e+ C+ O( S" N6 i3 n  T9 B: R' Z
其中SetCellString是Cell插件提供的接口方法。这样就实现了从Java Applet到华表的Cell插件的调用。2 _8 R( g7 U) h' U% K# n! U# U' ]
3 C/ Y4 V* X8 Y
. l1 K+ J1 }5 p2 H/ A0 D
五、结论7 ]% L! W4 Z2 E
在这个应用系统中,我们只利用Cell插件的打印预览和打印两项功能,不用它做屏幕显示。所有打印格式和数据都在Java Applet中准备好,按单元格向Cell插件设置格式和数据,由Cell插件完成分页和打印功能。
# w; d: `8 N4 S0 G* h  d, E5 U
) T9 {$ }, c5 A2 O6 ]9 F这是一种表现与数据分离的方式:Java Applet中只组织打印数据,所有打印的表现工作交给Cell插件完成,因此能够大大降低工作量。4 k% f: ]# `: l: _; L+ [  K3 z5 y

+ v+ E4 g& x/ Z1 U1 w7 ^. E" O4 c' E7 LCell插件除打印功能外,还具有输入、显示、编辑、图表等非常强大的功能,可以制作出非常复杂的报表。利用Cell插件,还可以将数据导出为Excel或PDF等格式的文件。
9 N4 ^7 b! G! Z. V% D) ]  S
5 [& w! V+ s! U+ G
- T3 h$ y, }0 R- p0 o六、参考文献, y! o3 i% Y: v: H. W% V- y
1 Cell插件文档:http://www.cellsoft.cc/csdn
6 D1 h) Y7 I, ?6 E0 E
' z6 U& z& D/ ^9 G0 [; u7 l$ O2 Java Plugin 文档:http://java.sun.com/j2se/1.4.1/docs/guide/plugin/4 v9 X; I2 a) z

+ r/ O6 D. Q3 i5 K! j; D9 o3 g1 A! H( Z- g
赵继江( v- ~( p- Q0 {
! s! X1 t" F! N$ q
2003年1月

TOP

发新话题