Часть 3. ODFDOM for Java: Упрощение программного управления документами и их данными

В третьей и последней части серии статей рассматривается использование ODFDOM for Java (Open Document Format (ODF) Document Object Model (DOM)) для создания текстовых документов, электронных таблиц и графических презентаций.

Ли Вэй, инженер-программист, IBM

Ли Вэй (Li Wei) работает инженером-программистом в Институте перспективных технологий подразделения IBM China Development Laboratory. Участвует в проектах по разработке стандартов, таких как ACORD, NAVA и ODF, а также является членом сообщества разработчиков ODF Toolkit. С ним можно связаться по адресу weili@cn.ibm.com.



28.02.2011

Примечание редактора. Обладаете информацией по данной теме? Хотите поделиться своим опытом? Принимайте участие в wiki-программе по программному обеспечению IBM Lotus.

Lotus Symphony wiki

Использование 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):

  • Первый элемент – <office:body>. Он является подэлементом корня (root) документа.
  • Следующий уровень – элемент <office:text>, который представляет все содержимое элементов документа, сохраняемое в выходной документ.
  • Перед <office:body> имеется еще один подэлемент корня документа – <office:automatic-styles>, использующийся для хранения различной информации о стиле элементов.
Листинг 1. Структура уровня content.xml текстового файла
<office:document-content>
    <office:automatic-style/>
      <office:body>
         <office:text/>
      </office:body>
</ office:document-content>

Здесь оба элемента, <office:style> и <office:automatic-styles>, определяют некоторые стили, но имеются определенные различия. Элемент <office:style> обычно используется для определения общих используемых стилей. Мы обычно применяем к элементам определенные в <office:style> стили путем установки имени стиля. С точки зрения ODF-редактора стиль, определенный в <office:style>, является набором значений характеристик, определенных пользователем.

С другой стороны, стиль, определенный в <office:automatic-styles>, содержит некоторые специальные свойства стиля. С точки зрения ODF-редактора это означает изменение определенных атрибутов объекта.

ODFDOM предоставляет объекты для представления ODF-пакета различных документов:

  • OdfTextDocument textDocument: соответствует объекту текстового файла (odt).
  • OdfFileDom contentDom: соответствует объекту XML-документа content.xml.
  • OdfFileDom stylesDom: соответствует объекту XML-документа styles.xml.

Объект текстового файла может использовать API для получения объекта содержимого (content.xml) и объекта стиля (styles.xml):

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

ODFDOM также предоставляет несколько объектов для представления различных элементов содержимого и стиля:

  • OdfOfficeAutomaticStyles contentAutoStyles: соответствующие элементы <office:automatic-styles> в content.xml.
  • OdfOfficeStyles stylesOfficeStyles: соответствующие элементы <office:styles> в styles.xml.
  • OdfOfficeText officeText: соответствующие элементы <office:text> в content.xml.

При помощи ODFDOM API можно также легко получить объект элемента content и объект элемента text:

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

ODFDOM предоставляет API для управления ODF-документами на уровне файлов, который может использоваться, например, для создания текстового файла, загрузки существующего текстового файла и сохранения файла:

  • OdfTextDocument odtDoc = OdfTextDocument.newTextDocument (); / / Создать текстовый файл
  • OdfTextDocument odtDoc = (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");

При применении этого кода с конкретными значениями характеристик к конкретному элементу документа создается стиль <office:automatic-style>.

Мы представили текстовый файл и примеры использования API. В следующих разделах мы рассмотрим ODFDOM-приложение, считывающее данные из XML-файла, а затем при помощи операции ODFDOM API сохраняющее данные в текстовый ODF-документ в указанном формате (см. листинги 3-7).

Листинг 3. XML-файл данных book.xml
<book> 
     <title> The ODFDOM tutorial </ title> 
     <author> IBM ODF team </ author> 
     <content> introduce ODFDOM usage </ content> 
</ book>
Листинг 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 odtDocument = OdfTextDocument.newTextDocument (); 
     OdfFileDom contentDom = outputDocument.getContentDom (); 
     OdfFileDom stylesDom = outputDocument.getStylesDom (); 
     contentAutoStyles = contentDom.getOrCreateAutomaticStyles (); 
     OdfOfficeStyles stylesOfficeStyles = odtDocument.getOrCreateDocumentStyles (); 
     officeText = outputDocument.getContentRoot (); 
     ) catch (Exception e) ( 
     System.err.println ( "Unable to create output file."); 
     System.err.println (e.getMessage ()); 
     odtDocument = 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")

Для открытия этого нового файла и просмотра результатов применения ODFDOM путем прямого доступа к API можно использовать OpenOffice или IBM® Lotus® Symphony™.


Создание файла электронной таблицы

Сначала рассмотрим основную структуру content.xml для документов электронных таблиц (spreadsheet) (см. листинг 8).

Листинг 8. Структура content.xml электронной таблицы
<office:document-content> 
<office :automatic-style/> 
<office :body> 
    <office:spreadsheet> 
        <table:table/> 
    </ Office: spreadsheet> 
</ office: body> 
</ Office: document-content>

В документе электронной таблицы основными элементами являются:

  • <table:table> – корневой элемент таблицы: все элементы содержимого таблицы являются его подэлементами.
  • <table:column> – указывает ширину электронной таблицы и определения стиля по умолчанию.
  • <table:row> – представляет строку таблицы, состоит из нескольких элементов <table:cell>.

Для элемента <table:cell> обычно необходимо указать два свойства - office:value-type и office: value; обычно это делается при помощи подэлементов <text:p>.

ODFDOM имеет несколько объектов, относящихся к функциональности таблицы

OdfSpreadsheetDocumentcontent.xml
OdfTable <table:table>
OdfTableColumn<table:table-column>
OdfTableRow<table:table-row>
OdfTableCell<table:table-cell>

где:

  • объект OdfTable представляет таблицу документа;
  • OdfTableColumn используется для указания столбцjd в таблице^ количество столбцов устанавливается значением свойства TableNumberColumnsRepeatedAttribute;
  • OdfTableRow используется для представления строк таблицы; одна строка состоит из одного или нескольких объектов OdfTableCell;
  • OdfTableCell – это модуль, составляющий элемент table: каждый объект cell может использоваться для размещения значений, абзацев и другого текстового содержимого. Обычно нужно установить значения трех следующих свойств:
    • OfficeValueAttribute
    • OfficeValueTypeAttribute
    • TextContent

OfficeValueTypeAttribute используется для указания типа сохраняемых данных (текст, числа, дата, время, формулы и т.д.); OfficeValueAttribute используется для сохранения значений; TextContent используется для сохранения значений, видимых пользователю.

Теперь мы создадим таблицу с тремя строками и четырьмя столбцами для демонстрации того, как применять некоторые операции ODFDOM API в функциональности table (см. листинг 9):

  1. Создаем объект электронной таблицы OdfSpreadsheetDocument.
  2. Получаем доступ к корню OdfOfficeSpreadsheet.
  3. Создаем объект OdfTable.
  4. Создаем элемент <table:column> и устанавливаем в атрибуте table:number-columns-repeated количество столбцов этой таблицы.
  5. Используем цикл для создания элементов <table:row> для каждой строки.
  6. Используем цикл для создания элементов <table:cell> для каждой ячейки в строке и заполняем их значениями.
  7. Сохраняем электронную таблицу.
Листинг 9. Создание электронной таблицы
int data [][]= ((1,2,3,4), (5,6,7,8), (9,10,11,12)); 
OdfSpreadsheetDocument odfdoc = 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"));

Функциональность table всегда содержит значения даты и времени, и представление этих значений может различаться для различных стран и регионов. ODFDOM может предоставить не только соответствующие средства для установки форматов даты и времени, но также и специальные классы стилей для многих форматов.

Например, OdfNumberDateStyle используется для обработки форматов дат, OdfNumberTimeStyle используется для обработки форматов времени, а OdfNumberStyle используется для обработки форматов чисел.

Эти элементы стиля должны помещаться под элементом <office:automatic-styles> (см. листинг 10) следующим образом:

  1. Получаем объект OdfAutomaticStyles с использованием getStylesDom ().
  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 из семейства table-cell.
  2. Получаем имя стиля даты и времени при помощи getStyleNameAttribute ().
  3. Задаем в свойстве style:data-stylename объекта стиля ячеек имя стиля даты и времени при помощи setStyleDataStyleNameAttribute().
  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):

  • <office:presentation> – это корневой элемент документа графической презентации.
  • Элемент <draw:page>, являющийся подэлементом <office:presentation>, представляет слайд в презентации. В <draw:page>, могут сохраняться только графические элементы, поэтому текстовые элементы, которые должны появиться в слайде, например, <text:title>, должны быть помещены под <draw:frame>.
  • <style:master-page> – это обобщенная страница-шаблон и подэлемент <style:master-style>. Стили, например background (фон), устанавливаются на страницах шаблона. Каждый слайд может быть ассоциирован со страницей шаблона, при этом к нему применяется соответствующий шаблон.
Листинг 12. Структура файла content.xml презентации
<office:document-content> 
<office :automatic-style/> 
<office :body> 
    <office:presentation> 
       <draw:page/> 
    </ office: presentation> 
</ office: body> 
</ Office: document-content>

В данном разделе мы продемонстрируем, как создать файл презентации, вставить слайд, вывести заголовок, применить шаблон и сохранить этот новый слайд.

В таблице перечислены ODF-классы, используемые в исходном коде.

Таблица 1. ODF-классы и их назначение
ODF-классНазначение
OdfPresentationDocumentФайл презентации.
OdfStyleDomСтиль DOM
OdfOfficePresentationЭлемент <office:presentation>.
OdfOfficeStylesЭлементы стилей документа <office:styles>.
OdfOfficeAutomaticStyleЭлемент <style:automatic-styles> помещается в автоматический стиль.
OdfStylePageLayout Элемент <style:page-layout> определяет схему страницы.
OdfOfficeMasterStylesЭлемент <office:master-styles> определяет стиль шаблона страницы.
OdfStyleMasterPageЭлемент <style:master-page> - это подэлемент <office:master-styles>, используемый для определения страниц шаблонов основного стиля.
OdfDrawPage Элемент <draw:page> используется для представления страницы в презентации или слайде.
OdfDrawFrameЭлемент <draw:frame> – это контейнерный элемент, в который помещаются другие элементы.

Вот список действий (см. листинг 13):

  1. Создаем объект OdfPresentationDocument.
  2. Получаем объект OdfOfficePresentation.
  3. Получаем объект OdfOfficeStyles, который представляет элемент стиля документа; создайте его, если этот элемент не существует.
  4. Создаем элемент <style:page-layout>; этот элемент находится под элементом OdfOfficeAutomaticStyle, поэтому его можно получить, используя getAutomaticStyles ().
  5. Получаем объект OdfOfficeMasterStyles при помощи метода getOfficeMasterStyles() класса OdfPresentationDocument.
  6. Создаем объект OdfStyleMasterPage, где необходимо указать имя этой мастер-страницы и имя стиля схемы. (Можно использовать имя стиля схемы, созданного на шаге 4).
  7. Документ презентации состоит из слайдов, поэтому следующим шагом является создание объекта OdfDrawPage при помощи метода newDrawPageElement (MasterPageStyleName), где мы можем указать мастер-страницу. После активизации этого метода мастер-страница используется для нового слайда.
  8. Поскольку в <draw:page> могут храниться только графические элементы, необходимо создать объект 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 officeMasterStyles = 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-документов: текстов, электронных таблиц и презентаций.


Благодарности

Автор выражает особую благодарность руководителю проекта Ин Чунь (Дейзи) Го (Ying Chun (Daisy) Guo) за ее вклад в данную статью.


Загрузка

ОписаниеИмяРазмер
Образец кодаPart3-ODFDOM-practice_EN.zip10 KБ

Ресурсы

Научиться

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Lotus
ArticleID=629874
ArticleTitle=Часть 3. ODFDOM for Java: Упрощение программного управления документами и их данными
publish-date=02282011