[返回]
计算机世界2002年8月8日

在IE浏览器上实现XML文档与EXCEL的数据交换

李 为

一、引言

XML技术已经逐渐成为Internet上数据交换的标准,XML本身主要是面向数据的,而处理XML的编程语言当首选Java,本文以一个具体的应用实例来讲述一项非常实用的技术,在浏览器上将XML文档映射为EXCEL表格数据。

二、应用分析

以一所大学每月的经费数据为例,大学包括若干个系,每个系的月经费由科研、教学、材料、工资费用三部分组成,其XML文档的树状结构如图1所示:

图1. XML文档的树状结构图

其中根元素拥有year和month两个属性用来标识时间;元素"系"拥有name属性标识名称;元素"费用"拥有type属性用来标识费用类型。下面是XML文件的样本:


<?xml version="1.0" encoding="UTF-8"?>
<清华大学 year="2002" month="01">
<系 name="计算机">
<费用 type="教学">100000.00</费用>
<费用 type="科研">200000.00</费用>
<费用 type="工资">20000.00</费用>
<费用 type="差旅">20000.00</费用>
<费用 type="材料">20000.00</费用>
<费用 type="其它">300000.00</费用>
<合计>660000.00</合计>
</系>
......
......
<合计>
<费用 type="教学">460000.00</费用>
<费用 type="科研">710000.00</费用>
<费用 type="工资">160000.00</费用>
<费用 type="差旅">160000.00</费用>
<费用 type="材料">160000.00</费用>
<费用 type="其它">810000.00</费用>
<合计>2460000.00</合计>
</合计>
</清华大学> 

我们的目的是在浏览器上按照我们需要的格式显示这个文件的数据,当然利用HTML中的Table表格很容易实现,但是许多用户特别是那些从事财务工作的用户习惯于利用Excel处理数据,希望能够在网页上显示Excel表格或者和数据导出为Excel文档,下面介绍如何在IE浏览器上实现这一功能。

应该特别指出的是,由于目前的绝大部分MIS系统中都是利用数据库存储数据的,因此上述XML文档往往是由数据库中的数据转换和汇总得来的,这种转换可以是静态的也可以是动态的;转换程序大多数用Java编写,可以在服务器作为后台运行,也可以嵌入客户端前台运行。关于从关系数据库表格转换到XML文档方面的内容不再本文讨论范围内,我们假设已经形成了要求的XML文档。


三、相关技术

1 Microsoft Spreadsheet Component:利用在网页中插入Spreadsheet组件可以在IE4.01以上版本的浏览器上实现类似Excel的表格,同时还可以实现于Excel数据交互,Spreadsheet的客户端实现比较简单,只要在HTML文本中插入如下语句即可:


<object id="Spreadsheet-id" classid="CLSID:0002E510-0000-0000-C000-000000000046" >
<param name="DisplayTitleBar" value="false"/>
<param name="DataType" value="HTMLData"/>
<param name="HTMLData" value="htmltable"
</object> 

其中Spreadsheet-id 代表用户定义ID号,htmltable代表我们输入的表格数据,(关于服务器端Spreadsheet的应用超出本文的讨论范围,这里不再说明)。

2 JAXP:Java API for XML Processing(JAXP)是Sun Java WEB 开发包的一部分,主要由SAX Parser、DOMBuilder和Transform(转换)几部分组成,关于JAXP的详细功能请参阅Java的相关文档,这里主要讲解应用Transform按照XSLT样式表转换XML文档。Transform应用类包括在javax.xml.transform和javax.xml.transform.stream包中,主要类有:TransformFactory,Transformer,StreamSource,StreamResult等。一般情况下,转换XML文档的过程如下:

TransformerFactory tFactory =TransformerFactory.newInstance();

//生成对象工厂

StreamSource styleSource=new StreamSource(new File(xsltfilename));

//生成xslt样式表的输入流

Transformer transformer = tFactory.newTransformer(styleSource);

//生成转换器对象

StreamSource source = new StreamSource(new File(xmlfilename));

//生成xml文档输入流

StreamResult result = new StreamResult(outstream);

//生成结果输出流

transformer.transform(source, result);

//执行转换

虽然IE5.0开始已经内嵌了XSLT转换器,但是作为服务器端的Java XSLT转换在功能和灵活性方面还是具有很多优势的:

(1)利用JAXP,在转换过程中可以进行复杂的业务逻辑处理。

(2)利用JAXP,可以实现动态选择转换样式表,可以实现用户定制样式。

(3)利用JAXP,可以实现从数据库或者其它形式的数据源到XML的映射,甚至可以不实现具体XML文档,在运行中生成XML数据,并把它按照XSLT样式表转换输出。

3 其它技术:本文中的实例应用XSLT、JSP等技术,这方面的内容有专门的文章论述,这里不再细述;另外,所有程序都是在Tomcat4.0下调试成功的。


四、实现

源代码包括两部分:XSLT样式表和JSP程序

XSLT样式表(tsinghua.xsl):是应用中的核心部分,包含了所有的页面表示逻辑。注意,代码中<和>是XML实体,分别代表"<"和">"


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>清华大学费用查询</title>
</head>
<body>
<div align="center">
清华大学<xsl:value-of select="/清华大学/@year"/>年
<xsl:value-of select="/清华大学/@month"/>月费用表
</div>
<div align="center">
<object id="Spreadsheet1" classid="CLSID:0002E510-0000-0000-C000-000000000046"
width="100%" height="90%">
<param name="DisplayTitleBar" value="false"/>
<param name="DataType" value="HTMLData"/>
<xsl:element name="param">
<xsl:attribute name="name">HTMLData</xsl:attribute>
<xsl:attribute name="value">
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;&lt;b&gt;系&lt;/b&gt;&lt;/th&gt;
<xsl:for-each select="/清华大学/系[1]/费用">
&lt;th&gt;&lt;b&gt;<xsl:value-of select="@type"/>&lt;/b&gt;&lt;/th&gt;
</xsl:for-each>
&lt;th&gt;&lt;b&gt;合计&lt;/b&gt;&lt;/th&gt;
&lt;/tr&gt;
<xsl:for-each select="/清华大学/系">
&lt;tr&gt;
&lt;td&gt;<xsl:value-of select="@name"/>&lt;/td&gt;
<xsl:for-each select="费用">
&lt;td&gt;<xsl:value-of select="."/>&lt;/td&gt;
</xsl:for-each>
&lt;td&gt;<xsl:value-of select="合计"/>&lt;/td&gt;
&lt;/tr&gt;
</xsl:for-each>
<xsl:for-each select="/清华大学/合计">
&lt;tr&gt;
&lt;td&gt;合计&lt;/td&gt;
<xsl:for-each select="费用">
&lt;td&gt;<xsl:value-of select="."/>&lt;/td&gt;
</xsl:for-each>
&lt;td&gt;<xsl:value-of select="合计"/>&lt;/td&gt;
&lt;/tr&gt;
</xsl:for-each>
&lt;/table&gt;
</xsl:attribute>
</xsl:element>
</object>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet> 

JSP程序(tsing_fee.jsp):JSP程序相对较为简单,仅用了几条语句实现转换的过程。


<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="javax.xml.transform.stream.StreamSource" %>
<%@ page import="javax.xml.transform.stream.StreamResult" %>
<%@ page import="javax.xml.transform.*" %>
<%@ page import="javax.xml.parsers.*" %>
<%@ page import="java.io.*" %>
<%
try{
Transformer transformer;
TransformerFactory tFactory=TransformerFactory.newInstance();
StreamSource stylesheet=new StreamSource("tsinghua.xsl");
transformer=tFactory.newTransformer(stylesheet);
StreamSource source=new StreamSource("tsinghua.xml");
StreamResult result=new javax.xml.transform.stream.StreamResult(out);
transformer.transform(source,result);
}catch(Exception e){
out.println(e.getMessage());
}catch(Throwable t){
out.println(t.getMessage());
}
%> 


五、配置

笔者是在Tomcat下配置该实例的,只要将tsinghua.xml、tsinghua.xsl和tsinghua.jsp三个文件拷贝到webapps下相应上下文的目录中即可,应该注意的是启动Tomcat前一定先要将JAXP包拷贝到相应上下文目录中的WEB-INF/lib目录下,JAXP包可以到http://java.sun.com网站下下载。

也可以把他们直接配置到Sun 的J2EE1.3上,J2EE1.3已经包括了Java的XML开发包。


六、运行结果

运行结果如图2所示,本文中为了便于理解,XML文档和XSLT样式表进行了简化,实际应用中,读者可以在样式表中加入更多的内容来实现美观的显示界面和复杂的业务逻辑。

图2. 运行结果图 


七、结论

本文描述的实例只是一个最为简单的应用,在实际应用中利用这几项技术可以实现十分复杂的应用。XML和Java的结合已经日益成为目前Internet开发的主流技术,Java的XML应用技术还包括许多深入的内容,有兴趣的读者可以参阅http://java.sun.com上的相关文档。