首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 笔记本电脑 | 北大青鸟 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Linux频道
中国IT教育
Google
首页 资讯动态 认证考试 新手入门 核心技术 高级技术 J2EE J2ME Java&XML 开源技术 其他技术 RSS订阅 论坛 专题
您现在的位置: 中国IT实验室 >> Java >> J2EE >> J2ee核心 >> 正文

让POI架起Java与Office之间的桥梁二


  五、通过eventusermodel读取文件
  
  通过eventusermodel读取文件要比使用usermodel复杂得多,但效率也要高不少,因为它要求应用程序一边读取数据,一边处理数据。
  
  eventusermodel实际上模拟了DOM环境下SAX处理XML文档的办法,应用程序首先要注册期望处理的数据,eventusermodel将在遇到匹配的数据结构时回调应用程序注册的方法。使用eventusermodel最大的困难在于你必须熟悉Excel工作簿的内部结构。
  
  在HSSF中,低层次的二进制结构称为记录(Record)。记录有不同的类型,每一种类型由org.apache.poi.hssf.record包中的一个Java类描述。例如,BOFRecord记录表示Workbook或Sheet区域的开始,RowRecord表示有一个行存在并保存其样式信息。
  
  所有具有CellValueRecordInterface接口的记录表示Excel的单元格,包括NumericRecord、LabelSSTRecord和FormulaRecord(还有其他一些,其中部分已被弃置不用,部分用于优化处理,但一般而言,HSSF可以转换它们)。
  
  下面是一个注册事件处理句柄的例子:
  
  private EventRecordFactory factory = new EventRecordFactory();
  factory.registerListener(new ERFListener() {
  public boolean processRecord(Record rec) {
  (got BOF Record);
  return true;
  }
  }, new short[] {BOFRecord.sid});
  factory.processRecords(someInputStream);
  
  六、HSSF电子表格结构
  
  如前所述,HSSF建立在POIFS的基础上。具体地说,Excel 97+文件是OLE 2复合文档( OLE 2 Compound Document),底层的OLE 2复合文档保存了一个总是命名为Workbook(Excel 95除外,HSSF不支持Excel 95)的流。
  
  然而,宏和图片并不保存在Workbook流,它们有自己独立的流,有时甚至会放到OLE 2 CDF文件之内的另一个目录。理想情况下,宏也应该被保留,不过目前POI项目中还没有合适的API来处理宏。
  
  每一个流之内是一组记录,一个记录其实就是一个字节数组,可分为记录头、记录体两部分。记录头指明了记录的类型(也即ID)以及后继数据的长度,记录体被分割成多个字段(Field),字段包含数值数据(包括对其他记录的引用)、字符数据或标记。
  
  Excel工作簿的顶级结构:
  
  Bla.xls {
  OLE2CDF headers
  "Workbook" stream {
  Workbook {
  Static String Table Record..
  Sheet names… and pointers
  }
  Sheet {
  ROW
  ROW
  …
  NUMBER RECORD (cell)
  LABELSST Record (cell)
  …
  }
  Sheet
  }
  }
  … images, macros, etc.
  Document Summary
  Summary
  
  七、通过HPSF读取文档属性
  
  在Microsoft Word、Excel、PowerPoint等软件中,用户可以通过“文件”→“属性”菜单给文档添加附加信息,包括文档的标题、主题、摘要、类别、关键词等,同时应用软件本身还会加入最后访问的用户、最后访问和修改/打印的日期时间等信息。
  
  文档的属性和正文是分开保存的。如前所述,OLE 2 CDF文件内部就象是一个容器,里面包含许多类似目录和文件的结构,而POIFS就是用来访问其中的文件的工具。这些文件也称为流,文档的属性就保存在POIFS文件系统中专用的流里面。
  
  以一个Word文档为例:虽然在资源管理器中你只看到一个叫做MyFile.doc的文档,其实在这个文档的内部,又包含了一个WordDocument、一个SummaryInformation和一个DocumentSummaryInformation文档;通常还会有其他的文档,这里暂且不管。
  
  你能够猜出这些文档(流)分别包含什么内容吗?不错,WordDocument包含了你在Word里面编辑的文本,文档的属性保存在SummaryInformation和DocumentSummaryInformation流里面。也许将所有属性保存在单个文档里面看起来太简单了,所以Microsoft决心要使用两个流,为了使事情更复杂一点,这两个流的名字前面还加上了八进制的\005字符??这是一个不可打印的字符,因此前面就把它省略了。
  
  Microsoft定义的标准属性有一个好处,它们并不在乎主文档到底是什么类型??不管是Word文档、Excel工作簿还是PowerPoint幻灯。只要你知道如何读取Excel文档的属性,就知道了如何读取其他文档的属性。
  
  读取文档属性其实并不复杂,因为Java程序可以利用POI项目的HPSF包。HPSF是 Horrible Property Set Format的缩写,译成中文就是“讨厌的属性集格式”。HPSF包是POI项目实现的读取属性工具,目前还不支持属性写入。
  
  对于读取Microsoft定义的标准属性,通过HPSF提供的API可以很方便地办到;但如果要读取任意属性集就要用到更一般化的API,可以想象它要比读取标准属性的API复杂不少。本文只介绍读取标准属性的简单API,因为对大多数应用程序来说这已经完全足够了。
  
  下面就是一个读取OLE 2 CDF文档的标题(title)属性的Java程序:
  
  import java.io.*;
  import org.apache.poi.hpsf.*;
  import org.apache.poi.poifs.eventfilesystem.*;
  
  /**
  * 读取OLE 2文档标题的示例程序,
  * 在命令行参数中指定文档的文件名字。
  */
  
  public class ReadTitle
  {
  public static void main(String[] args) throws IOException
  {
  final String filename = args[0];
  POIFSReader r     = new POIFSReader();
  r.registerListener(new MyPOIFSReaderListener(),
  "\005SummaryInformation");
  r.read(new FileInputStream(filename));
  }
  
  static class MyPOIFSReaderListener
  implements POIFSReaderListener
  {
  public void processPOIFSReaderEvent(POIFSReaderEvent event)
  {
  SummaryInformation si = null;
  try
  {
  si = (SummaryInformation)
  PropertySetFactory.create(event.getStream());
  }
  catch (Exception ex)
  {
  throw new RuntimeException
  ("属性集流\"" + event.getPath() +
  event.getName() + "\": " + ex);
  }
  
  final String title = si.getTitle();
  
  if (title != null)
  System.out.println("标题: \"" + title + "\"");
  else
  System.out.println("该文档没有标题.");
  }
  }
  }
【责编:admin】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·Oracle外键及外键约束修改行为
 ·开源软件测试工具学习专题
 ·JSP Web开发 入门基础到高手进阶教程
 ·JavaFX—是Java桌面的新希望么?
 ·安全至上 .NET开发安全策略
 ·测试用例设计之道-测试用例学习专题
 ·面向Java开发人员的Scala指南
 ·Java设计模式之实例详解
 ·Oracle数据库11g 面向DBA和开发人员的重要新特性
 ·桌面应用软件编程 J2SE技术详解
 今日更新
 社区讨论
 博客论点
 频道精选
 Java 频道导航