国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

讓POI架起Java與Office之間的橋梁二

2019-11-18 12:26:54
字體:
來源:轉載
供稿:網友

  五、通過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("該文檔沒有標題.");
  }
  }
  }

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 常德市| 聊城市| 崇仁县| 光山县| 抚顺市| 巩留县| 竹北市| 承德市| 方城县| 荥经县| 镇远县| 托克托县| 宜兰市| 九龙县| 独山县| 井冈山市| 凉城县| 融水| 永登县| 桦川县| 酉阳| 原阳县| 巴南区| 化德县| 横峰县| 登封市| 上饶县| 鹤山市| 屏东县| 运城市| 金乡县| 高阳县| 巫山县| 闵行区| 卓尼县| 遂川县| 西乡县| 南投县| 和硕县| 陈巴尔虎旗| 扬州市|