ODFDOM for Java:簡化文件及其資料的程式控制

genusBIT發表於2010-06-23

轉自 http://www.ibm.com/developerworks/cn/lotus/symphony-odfdom-pt3/index.html

使用 ODFDOM 來建立文字、電子表格和演示圖形文件

首先,我們簡要描述一下 ODF 文件結構。ODF 文件儲存在一個 ZIP 壓縮包中,它包含 content.xml、style.xml 及其他若干文件。

Content.xml 用來儲存文件內容,style.xml 用來儲存文件樣式資訊。content.xml 檔案也含有一些樣式資訊,可以用來自動建立一些預設值,如字型和顏色。

一般來說,操作一個 ODF 文件分四步:

  1. 載入已有 ODF 文件或建立 ODF 文件。
  2. 向 ODF 文件插入內容。
  3. 為資訊的不同部分設定樣式。
  4. 儲存文件。

ODFDOM 現在提供一些 API,藉助它們,可以輕鬆完成這四步主要操作。


建立文字檔案

在本小節中,我們將演示一個簡單用例:讀取一個 XML 檔案並輸出到 ODF 文件。

作為文字檔案,content.xml 層級如下(見清單 1):

  • 第一個元素是 ,它是文件根目錄的子元素。
  • 下一級是 元素,它表示所有要儲存在輸出文件中的文件元素。
  • 在 之前的 是文件根目錄的另一個子元素,用於儲存元素的各種樣式資訊。

清單 1. 文字檔案 content.xml 級的結構

    
      
         
      
 office:document-content>
				

此處,<style><style><automatic-styles><style>

另一方面, 中定義的樣式包含一些特別的樣式屬性。從 ODF 編輯器的角度看,它用於編輯物件的某些屬性。

ODFDOM 提供物件來表示各種文件的 ODF 包:

  • OdfTextDocument textDocument:對應於一個文字檔案(odt)物件。
  • OdfFileDom contentDom:對應於 content.xml 的 XML 文件物件。
  • OdfFileDom stylesDom:對應於 styles.xml 的 XML 文件物件。

文字檔案物件可以使用 API 來獲取內容物件(content.xml)和樣式物件(styles.xml):

  • OdfFileDom contentDom = textDocument.getContentDom()
  • OdfFileDom stylesDom = textDocument.getStylesDom()

ODFDOM 還提供多個物件來表示各種內容和樣式元素:

  • OdfOfficeAutomaticStyles contentAutoStyles:對應 content.xml 中
  • OdfOfficeStyles stylesOfficeStyles:對應 styles.xml 中
  • OdfOfficeText officeText:對應 content.xml 中

用 ODFDOM API 獲取內容元素物件和文字元素物件也很容易:

  • OdfOfficeAutomaticStyles autoStyles = textDocument.getContentDom (). GetAutomaticStyles ()
  • OdfOfficeStyles styles = textDocument.getDocumentStyles ();
  • OdfOfficeText text = (OfficeText) textDocument.getContentRoot ();

ODFDOM 還提供一個 API 來對 ODF 文件進行檔案級操作,例如,可以用來建立文字檔案、載入已有檔案以及儲存檔案:

  • OdfTextDocument dtDoc = OdfTextDocument.newTextDocument (); / / 建立文字檔案
  • OdfTextDocument dtDoc = (OdfTextDocument) OdfDocument.loadDocument ( "text.odt"); / / 載入已有文字檔案
  • odtDoc.save ( "text.odt") / / 儲存檔案

當然,文字檔案沒有豐富的樣式屬性也不行,如文字字型、段落佈局、專案符號。因此,ODFDOM 也有處理這些樣式屬性的方法:

  • OdfStyle. style. = odtDoc.getDocumentStyles (). getStyle. ( "myStyle",
    OdfStyleFamily.Paragraph);
    / / 從文字檔案獲取使用者定義的樣式(style)物件
  • style.setProperty (OdfStyleTextProperties.FontWeight, "bold");
    / / 將樣式設定為特定屬性值

設定文字樣式屬性的程式碼如清單 2 所示。


清單 2. 設定文字樣式屬性的程式碼
OdfTextParagraph para; 
para.setProperty (OdfStyleTextProperties.FontSize, "17pt"); 
para.setProperty (OdfStyleParagraphProperties.TextAlign, "left"); 
para.setProperty (OdfStyleChartProperties.DataLabelNumber, "value"); 
					

使用特徵值的程式碼可以應用到特定文件元素,這種方式產生的樣式是

我們介紹了文字檔案及 API 的重要用法。在下面的例子中,我們將看一個 ODFDOM 應用程式,它從 XML 檔案中讀出資料,然後通過 ODFDOM API 操作,資料以特定格式儲存到 ODF 文字文件中(見清單 3-7)。


清單 3. XML 資料檔案 book.xml
 
      The ODFDOM tutorial  title> 
     <author> IBM ODF team  author> 
     <content> introduce ODFDOM usage  content> 
 book>
				</content></author>


清單 4. 使用 Java DOM API 來解析要讀取的 XML 文件
DocumentBuilder builder = null; 
  inputDocument = null; 
  try ( 
      inputXPath = XPathFactory.newInstance (). newXPath (); 
      builder = DocumentBuilderFactory.newInstance (). newDocumentBuilder (); 
      inputDocument = builder.parse ( "book.xml"); 
  ) catch (IOException e) ( 
      System.err.println ( "Unable to read input file."); 
      System.err.println (e.getMessage ()); 
  ) catch (Exception e) ( 
      System.err.println ( "Unable to parse input file."); 
      System.err.println (e.getMessage ()); 
)
				


清單 5. 建立文字 ODF 物件
try ( 
     OdfTextDocument dtDocument = OdfTextDocument.newTextDocument (); 
     OdfFileDom contentDom = outputDocument.getContentDom (); 
     OdfFileDom stylesDom = outputDocument.getStylesDom (); 
     contentAutoStyles = contentDom.getOrCreateAutomaticStyles (); 
     OdfOfficeStyles stylesOfficeStyles = odtDocument.getOrCreateDocumentStyles (); 
     fficeText = outputDocument.getContentRoot (); 
     ) catch (Exception e) ( 
     System.err.println ( "Unable to create output file."); 
     System.err.println (e.getMessage ()); 
     dtDocument = null; 
) 
				

由於內容和樣式需要額外資訊來補充完整,必須向這個新文字檔案的內容 DOM 樹插入內容元素,並向內容和樣式 DOM 樹插入自動樣式元素(見清單 6 和 7)。


清單 6. 將 XML 內容讀到 ODF 文字檔案中
NodeList booklist = inputDocument.getElementsByTagName ( "book"); 
Node book = booklist [0]; 
String title = inputXPath.evaluate ( "book / title", book); 
String author = inputXPath.evaluate ( "book / author", book); 
String content = inputXPath.evaluate ( "book / content", book); 
OdfTextHeading heading = (OdfHeading) officeText.newTextHElement (title); 
(OdfTextParagraph) para = (OdfTextParagraph) newTextPElement (); 
para. addContent (content);
				


清單 7. 樣式應用到文字內容
OdfStyle. style1 = odtDocument.getOrCreateDocumentStyles (). 
NewStyle. ( "hStyle", OdfStyleFamily.Text); 
style.setProperty (OdfTextProperties.FontWeight, "bold"); 
style.setProperty (OdfTextProperties.FontStyle, "italic"); 
style.setProperty (OdfTextProperties.FontSize, "16"); 
heading.setStyleName ( "hStyle"); 

OdfStyle. style2 = odtDocument.getOrCreateDocumentStyles (). 
NewStyle. ( "pStyle", OdfStyleFamily.Text); 
style.setProperty (OdfTextProperties.FontStyle, "italic"); 
style.setProperty (OdfTextProperties.FontSize, "10"); 
para.setStyleName ( "pStyle"); 
				

最後,儲存 ODT 文字檔案:

odtDocument.save ( "text.odt")

可以使用 OpenOffice 或 IBM® Lotus® Symphony™ 來開啟新檔案,並看到 ODFDOM 如何通過直接訪問 API 產生結果。


建立電子表格檔案

首先,我們看一下電子表格文件的 content.xml 的主要結構(見清單 8)。


清單 8. 電子表格 content.xml 的結構
 
 
 
     
        
Office: spreadsheet> office: body> Office: document-content>

電子表格文件中,主要元素有:

  • 是表的根元素,表內容的所有元素都是它的子元素
  • 指定電子表格的寬度,是預設的樣式定義
  • 表示表格行,由多個 元素組成

對於 元素,兩個屬性 office:value-type 和 office: value,通常必須用子元素

指定。

ODFDOM 有很多與檔案相關的物件:

OdfSpreadsheetDocument content.xml
OdfTable
OdfTableColumn
OdfTableRow
OdfTableCell

其中:

  • OdfTable 物件表示電子表格的表。
  • OdfTableColumn 用來指定電子表格的列,列數通過 TableNumberColumnsRepeatedAttribute 屬性值設定。
  • OdfTableRow 用來表示表格行。一行由一個或多個 OdfTableCell 物件組成。
  • OdfTableCell 是組成表格元素的單元,每個單元格物件可以用來放值、段落和其他文字內容;通常需要設定三個屬性值:
    • OfficeValueAttribute
    • OfficeValueTypeAttribute
    • TextContent

OfficeValueTypeAttribute 用來指定儲存資料的型別(字元、數字、日期、時間、公式等);OfficeValueAttribute 用來儲存值;TextContent 用來儲存使用者看到的值。

現在建立一個三行四列的表格來演示如何對錶特性使用 ODFDOM API 操作(見清單 9):

  1. 建立 OdfSpreadsheetDocument 電子表格物件。
  2. 得到 OdfOfficeSpreadsheet 根。
  3. 建立 OdfTable 物件。
  4. 建立 元素,設定 table:number-columns-repeated 屬性為表中列數。
  5. 使用迴圈為每一行建立 元素。
  6. 使用迴圈為每行中的單元格建立 元素,並填入值。
  7. 儲存電子表格。

清單 9. 構造電子表格
int data [][]= ((1,2,3,4), (5,6,7,8), (9,10,11,12)); 
OdfSpreadsheetDocument dfdoc = OdfSpreadsheetDocument.newSpreadsheetDocument (); 
OdfOfficeSpreadsheet spreadsheet = odfdoc.getContentRoot (); 
OdfTable table = (OdfTable) spreadsheet.newTableTableElement (); 
OdfTableColumn column = (OdfTableColumn) table.newTableTableColumnElement (); 
column.setTableNumberColumnsRepeatedAttribute (new Integer (4)); 
for (int i = 0; i <3; i) ( 
OdfTableRow row = (OdfTableRow) table.newTableTableRowElement (); 
/ / row.setStyleName ( "ro1"); 
for (int j = 0; j <4; j) ( 
OdfTableCell cell = (OdfTableCell) row.newTableTableCellElement (); 
cell.setOfficeValueAttribute (new Double (data [i] [j])); 
cell.setOfficeValueTypeAttribute ( "float"); 
cell.setTextContent ((new Double (data [i] [j]). toString ())); 
) 
) Odfdoc.save (ResourceUtilities.createTestResource ( "table3R4C.ods")); 
				

表特性經常包含日期和時間值,這些值的表示在各國家和地區會不一樣。ODFDOM 不僅提供合適的方法來設定日期和時間格式,還有一些特別的類用於這種格式。

例如,OdfNumberDateStyle. 用於處理日期格式,OdfNumberTimeStyle. 用來處理時間格式,OdfNumberStyle. 用來處理數字格式。

這些樣式元素可以放在 元素下(見清單 10),如下所示:

  1. 用 getStylesDom () 取得 OdfAutomaticStyles 物件。
  2. 建立對應類的物件。
  3. 設定樣式物件的具體格式。

清單 10. 設定數字樣式
OdfOfficeAutomaticStyles autoStyles = odfdoc.getStylesDom (). GetAutomaticStyles (); 
OdfNumberDateStyle. dataStyle. = (OdfNumberDateStyle) 
autoStyles.newNumberDateStyleElement ( "numberDateStyle"); 
dataStyle.buildFromFormat ( "yyyy-MM-dd"); 
OdfNumberTimeStyle. timeStyle. = (OdfNumberTimeStyle) 
autoStyles.newNumberTimeStyleElement ( "numberTimeStyle"); 
timeStyle.buildFromFormat ( "hh: mm: ss"); 
OdfNumberStyle. numberStyle. = (OdfNumberStyle) 
autoStyles.newNumberNumberStyleElement ( "numberStyle"); 
numberStyle.buildFromFormat ( "# 0.00"); 
				

然後指定單元格樣式,然後將其和數字樣式物件關聯到單元格樣式物件(見清單 11):

  1. 建立 OdfStyle. 物件,它的層次是表單元格。
  2. 用 getStyleNameAttribute () 取得日期和數字樣式名。
  3. 用 setStyleDataStyleNameAttribute() 設定日期和數字樣式名為單元格樣式物件的 style.:data-stylename 屬性。
  4. 將單元格樣式應用到具體的單元格。

清單 11. 應用單元格樣式
Cell style. for date cells:

OdfStyle. style; 
style. = autoStyles.newStyle. (OdfStyleFamily.TableCell); 
String dataCellStyleName = style.getStyleNameAttribute (); 
style.setStyleDataStyleNameAttribute ( "numberDateStyle"); 
cell.setStyleName (dataCellStyleName); 

And for time cells:

style. = autoStyles.newStyle. (OdfStyleFamily.TableCell); 
String timeCellStyleName = style.getStyleNameAttribute (); 
style.setStyleDataStyleNameAttribute ( "numberTimeStyle"); 
cell.setStyleName (timeCellStyleName); 

And for the temperatures:

style. = autoStyles.newStyle. (OdfStyleFamily.TableCell); 
String numberCellStyleName = style.getStyleNameAttribute (); 
style.setStyleDataStyleNameAttribute ( "numberStyle"); 
cell.setStyleName (numberCellStyleNam); 
				

本例中,建立了一個簡單的電子表格,但實際上,電子表格可能會相當複雜。例如,可能有跨行和跨列的單元格,以及大量樣式和嵌入物件和媒體的應用程式。

這些複雜的特性可以通過 ODFDOM API 實現,儘管程式碼會很複雜。但隨著 ODFDOM 發展,這些複雜的電子表格的建立會變得越來越簡單。


建立演示檔案

讓我們從定義演示 content.xml 中的相關術語開始(見清單 12):

  • 電子演示文件的根元素。
  • 的子元素,表示一張幻燈片。只有影像元素才能儲存在 中,因此文字元素,如 ,必須先放在 <frame></frame>

清單 12. 演示檔案 content.xml 的結構
 
 
 
     
        
     office: presentation> 
 office: body> 
 Office: document-content> 
				

在本小節中,我們將展示如何建立演示檔案、插入幻燈片、列出標題、應用母版頁模板,還有儲存新幻燈片。

表 1 列舉出程式碼中用到的 ODF 類。


表 1. ODF 類和用途
ODF 類 用途
OdfPresentationDocument 演示檔案
OdfStyleDom Style. DOM
OdfOfficePresentation 元素
OdfOfficeStyles 文件樣式元素
OdfOfficeAutomaticStyle 放在自動樣式中
OdfStylePageLayout 定義頁面佈局
OdfOfficeMasterStyles 定義頁面的母版樣式
OdfStyleMasterPage 子元素,用於定義主樣式母版頁
OdfDrawPage 元素用於表示一個演示頁面或一張幻燈片
OdfDrawFrame

步驟如下(見清單 13):

  1. 建立 OdfPresentationDocument 物件。
  2. 獲取 OdfOfficePresentation 物件。
  3. 獲取 OdfOfficeStyles 物件,它表示文件樣式元素;如果該元素不存在,就建立一個。
  4. 建立 元素;該元素在 OdfOfficeAutomaticStyle. 元素下,因此可以使用 getAutomaticStyles () 得到。
  5. 使用 OdfPresentationDocument 類的 getOfficeMasterStyles() 方法獲取 OdfOfficeMasterStyles 物件。
  6. 建立 OdfStyleMasterPage 物件,其中我們必須指定母版頁名稱和佈局樣式名稱。(可以使用第 4 步中的佈局樣式名稱。)
  7. 演示文件由多個幻燈片組成,所以下一步是用 newDrawPageElement 方法(MasterPageStyleName)建立 OdfDrawPage 物件,這裡我們可以指定母版頁。呼叫該方法後,母版頁就應用到新幻燈片。
  8. 由於只有圖形元素能儲存到 中,因此我們需要建立 OdfDrawFrame. 物件來新增內容。
  9. 我們建立兩個 OdfDrawFrame. 物件。一個用來儲存標題; 另一個用來儲存圖片。

至此,演示文件已建立完成,現在可以儲存為 ODP 文件,並使用 OpenOffice 或 IBM Lotus Symphony 開啟。


清單 13. 建立演示檔案
OdfPresentationDocument presentationDoc = 
OdfPresentationDocument.newPresentationDocument (); 
OdfOfficePresentation presentation1 = presentationDoc.getContentRoot (); 
presentationDoc.getOrCreateDocumentStyles (); 
presentationDoc.getStylesDom (). getAutomaticStyles (). 
newStylePageLayoutElement ( "PM01"); 
OdfOfficeMasterStyles fficeMasterStyles = presentationDoc.getOfficeMasterStyles (); 
                                                            
    OdfStyleMasterPage masterPage = (OdfStyleMasterPage) officeMasterStyles.
    newStyleMasterPageElement ( "master-name-1", "PM01"); 
    OdfDrawPage page4 = (OdfDrawPage) presentation1.newDrawPageElement 
    ( "master-name-1"); 
    OdfDrawFrame. frame1 = (OdfDrawFrame) page4.newDrawFrameElement (); 
    frame1.newDrawTextBoxElement (). setTextContent ( "title"); 
    OdfDrawFrame. frame2 = (OdfDrawFrame) page4.newDrawFrameElement (); 
    frame2.newDrawImageElement (). setXlinkHrefAttribute ( "http://impage"); 
    presentationDoc.save ( "presentation.odp"); 
				


結束語

在對本文中三個例子的詳細講解中,我們演示瞭如何使用 ODFDOM API 來建立文字、電子表格、演示 ODF 文件的內容、樣式、以及其他特性。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14751907/viewspace-665978/,如需轉載,請註明出處,否則將追究法律責任。

相關文章