menu

silverghost

世界可以想象,世界可以创造

Avatar

转载--利用Java操作Office2007成为可能

利用Java操作Office2007成为可能

之前从来都没有想过使用Java来操作Office,今天在InfoQ中文站上逛悠了一圈,发现了一篇名为《用Java操作Office 2007》的译文,原文作者为:Ted Neward ,译者为:张立。

其中,有这样一段关键文字:

由于Office文档(主要是Word,Excel和PowerPoint)是存储在一个二进制格式文件中,在COM中被称为结构化存储格式, 是一个通过COM接口的层次化二进制格式。 对COM开发者(或者其他使用COM相关语言的开发者,如Visual Basic, Delphi 和C++/ATL)而言非常方便,但产生的文件对于那些不能“讲COM”的语言是无法访问的。有许许多多的应用程序都是为了让Java语言可以访问这些文件的内容;比如大家都知道Excel可以读取逗号分隔符文件(CSV),因此,Java应用程序相应将数据导出到Excel友好的格式时一般会选用CSV 格式(或是其他丑陋的格式)。Word则是可以读取富文本格式(RTF)文件,而RTF标准是公开和有详细文档的。Office的后来者,Office 2003,引入了一个新的XML格式(WordML),Java开发者可以用它来读写Office文档,但是这些格式并没有很好的文档,Java开发者频繁的发现自己是通过试错法来进行WordML格式的学习。 各种各样的开源项目都参与进来想要解决这个问题,比如Apache的POI框架,可以用来读写Excel文档,还有各种各样的Java-COM解决方案,这些解决方案一般倾向于使用和Office自己使用的结构化存储应用程序接口相同的应用程序接口进行Excel文档的读写,但很难满足需要,直到现在,开发者不得不指出Office文档格式的内部结构是一个非常复杂的结构,另外一点毋庸置疑的是它是一个没有完整文档的结构。 总体上来说,如果温和一点说的话,Java/Office的故事是一个非常讨厌的境况。对于Java的开发人员而言,他们要么一边嘴里说着“Office 这种破东西怎么还会有人想去用它”一边用记忆里的伊索寓言来安慰自己,要么干脆告诉那些使用Office的客户由于Microsoft和Sun两家公司之间的诉讼,Java不能操作Office。 对于Office 2007来说,微软毫无疑问的迈出了解决这些问题的一大步。没有比原始的JDK更复杂的东西---也就是说并不要求使用一些第三方的库---Java应用程序现在可以读写任何Office 2007的文档,这是由于Office 2007文档现在使用的是XML文档的ZIP格式文件。 这种格式被称作“OpenMXL”规范并且已经被提交到欧洲计算机制造商协会(ECMA),这个协会同样拥有C#语言和CLI运行时规范,所有的 OpenXML规范现在都可以被任何人自由的从ECMA的网站下载。 除了这些,再安装好Office 2007(为了验证和作一些测试)和一个标准的Java6 JDK安装,Java现在可以打开任何的Office 2007文档,找出来文档中间的内容,操作它们,并且再次保存这些数据。
“.docx”文件是OpenXML格式的,微软的文档中声称该格式是XML文档的ZIP压缩格式文件,这些文件中包含了文档中的数据和格式,存储的方式与之前的Office版本中的二进制结构化存储应用程序接口存储数据的方式有些类似。如果这是真的,那么使用Java中提供的用来处理ZIP和 TAR格式的“jar”实用工具应该可以展示这些内容,而事实上,它的确可以……在命令提示符中运行:“jar tvf Hello.docx” 即可查看到Word2007的文档结构内容。
下面是我的测试结果:


一、首先使用MS Word 2007字处理软件新建一个“.docx”文档,并在文档内录入一段简要文字信息并保存退出。


二、打开命令提示符工具(运行cmd.exe),并转到第一步中Word2007文档的存档路径,在命令窗口中输入jar tvf Hello.docx并回车,即可看到如图效果:

三、实质上,使用7-Zip解压工具可以更直观地看到和提取详细的文档内容。


四、打开word\document.xml文档,内容格式很紧凑,我稍稍整理了一下,可以看到Hello.docx文档的文字信息均包含在些 XML文档中。


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
	<w:body>
		<w:p w:rsidR="000C1A38" w:rsidRDefault="00DE3253">
			<w:pPr>
				<w:rPr>
					<w:rFonts w:hint="eastAsia"/>
				</w:rPr>
			</w:pPr>
			<w:r>
				<w:rPr>
					<w:rFonts w:hint="eastAsia"/>
				</w:rPr>
				<w:t>这是一个关于</w:t>
			</w:r>
			<w:r>
				<w:rPr>
					<w:rFonts w:hint="eastAsia"/>
				</w:rPr>
				<w:t>Java</w:t>
			</w:r>
			<w:r>
				<w:rPr>
					<w:rFonts w:hint="eastAsia"/>
				</w:rPr>
				<w:t>操作</w:t>
			</w:r>
			<w:r>
				<w:rPr>
					<w:rFonts w:hint="eastAsia"/>
				</w:rPr>
				<w:t>Office2007</w:t>
			</w:r>
			<w:r>
				<w:rPr>
					<w:rFonts w:hint="eastAsia"/>
				</w:rPr>
				<w:t>的一个简单的仅包含文字信息的测试文档。</w:t>
			</w:r>
		</w:p>
		<w:sectPr w:rsidR="000C1A38" w:rsidSect="000C1A38">
			<w:pgSz w:w="11906" w:h="16838"/>
			<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/>
			<w:cols w:space="425"/>
			<w:docGrid w:type="lines" w:linePitch="312"/>
		</w:sectPr>
	</w:body>
</w:document>


可以看到,这样的一个XML文档,用Java便很容易处理了。

如果不使用三方jar库,JDK中自带的类库也可以处理XML文档。所以,在你的Java代码中大致需要包含以下几个package:

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

呵呵!原来只听说过通过COM访问Office,没想到短短的几年,还可以这样通过XML技术操作Office,有意思!

By CodingMouse

2009 年04月09日

可怕的 XML……

趋势是好的,这样可以用java来操作和控制docx了