Перейти к основному содержимому

Microsoft Word Processing на Java с Apache POI

· 6 мин. чтения

1. Обзор

Apache POI — это библиотека Java для работы с различными форматами файлов, основанная на стандартах Office Open XML (OOXML) и формате составного документа Microsoft OLE 2 (OLE2).

В этом руководстве основное внимание уделяется поддержке Apache POI для Microsoft Word , наиболее часто используемого формата файлов Office. В нем описаны шаги, необходимые для форматирования и создания файла MS Word, а также способы анализа этого файла.

2. Зависимости Maven

Единственная зависимость, необходимая для Apache POI для обработки файлов MS Word, это:

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>

Щелкните здесь для получения последней версии этого артефакта.

3. Подготовка

Давайте теперь рассмотрим некоторые элементы, используемые для облегчения создания файла MS Word.

3.1. Файлы ресурсов

Мы соберем содержимое трех текстовых файлов и запишем их в файл MS Word с именем rest-with-spring.docx .

Кроме того, файл logo-leaf.png используется для вставки изображения в этот новый файл. Все эти файлы существуют в пути к классам и представлены несколькими статическими переменными:

public static String logo = "logo-leaf.png";
public static String paragraph1 = "poi-word-para1.txt";
public static String paragraph2 = "poi-word-para2.txt";
public static String paragraph3 = "poi-word-para3.txt";
public static String output = "rest-with-spring.docx";

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

3.2. Вспомогательный метод

Основной метод, состоящий из логики, используемой для создания файла MS Word, который описан в следующем разделе, использует вспомогательный метод:

public String convertTextFileToString(String fileName) {
try (Stream<String> stream
= Files.lines(Paths.get(ClassLoader.getSystemResource(fileName).toURI()))) {

return stream.collect(Collectors.joining(" "));
} catch (IOException | URISyntaxException e) {
return null;
}
}

Этот метод извлекает содержимое, содержащееся в текстовом файле, расположенном в пути к классам, имя которого является переданным строковым аргументом. Затем он объединяет строки в этом файле и возвращает объединяющую строку String .

4. Создание файла MS Word

В этом разделе приведены инструкции по форматированию и созданию файла Microsoft Word. Прежде чем работать с какой-либо частью файла, нам нужно иметь экземпляр XWPFDocument :

XWPFDocument document = new XWPFDocument();

4.1. Форматирование заголовка и подзаголовка

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

XWPFParagraph title = document.createParagraph();
title.setAlignment(ParagraphAlignment.CENTER);

Содержимое абзаца должно быть заключено в объект XWPFRun . Мы можем настроить этот объект для установки текстового значения и связанных с ним стилей:

XWPFRun titleRun = title.createRun();
titleRun.setText("Build Your REST API with Spring");
titleRun.setColor("009933");
titleRun.setBold(true);
titleRun.setFontFamily("Courier");
titleRun.setFontSize(20);

Нужно уметь догадываться о назначении set-методов по их именам.

Аналогичным образом мы создаем экземпляр XWPFParagraph , содержащий подзаголовок:

XWPFParagraph subTitle = document.createParagraph();
subTitle.setAlignment(ParagraphAlignment.CENTER);

Давайте также отформатируем подзаголовок:

XWPFRun subTitleRun = subTitle.createRun();
subTitleRun.setText("from HTTP fundamentals to API Mastery");
subTitleRun.setColor("00CC44");
subTitleRun.setFontFamily("Courier");
subTitleRun.setFontSize(16);
subTitleRun.setTextPosition(20);
subTitleRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);

Метод setTextPosition устанавливает расстояние между подзаголовком и последующим изображением, а setUnderline определяет шаблон подчеркивания.

Обратите внимание, что мы жестко кодируем содержимое как заголовка, так и подзаголовка, поскольку эти операторы слишком короткие, чтобы оправдать использование вспомогательного метода.

4.2. Вставка изображения

Изображение также должно быть заключено в экземпляр XWPFParagraph . Мы хотим, чтобы изображение располагалось по центру по горизонтали и располагалось под подзаголовком, поэтому следующий фрагмент должен быть помещен под приведенным выше кодом:

XWPFParagraph image = document.createParagraph();
image.setAlignment(ParagraphAlignment.CENTER);

Вот как установить расстояние между этим изображением и текстом под ним:

XWPFRun imageRun = image.createRun();
imageRun.setTextPosition(20);

Изображение берется из файла в пути к классам, а затем вставляется в файл MS Word с указанными размерами:

Path imagePath = Paths.get(ClassLoader.getSystemResource(logo).toURI());
imageRun.addPicture(Files.newInputStream(imagePath),
XWPFDocument.PICTURE_TYPE_PNG, imagePath.getFileName().toString(),
Units.toEMU(50), Units.toEMU(50));

4.3. Форматирование абзацев

Вот как мы создаем первый абзац с содержимым, взятым из файла poi-word-para1.txt :

XWPFParagraph para1 = document.createParagraph();
para1.setAlignment(ParagraphAlignment.BOTH);
String string1 = convertTextFileToString(paragraph1);
XWPFRun para1Run = para1.createRun();
para1Run.setText(string1);

Очевидно, что создание абзаца аналогично созданию заголовка или подзаголовка. Единственная разница здесь заключается в использовании вспомогательного метода вместо жестко заданных строк.

Аналогичным образом мы можем создать два других абзаца, используя содержимое файлов poi-word-para2.txt и poi-word-para3.txt :

XWPFParagraph para2 = document.createParagraph();
para2.setAlignment(ParagraphAlignment.RIGHT);
String string2 = convertTextFileToString(paragraph2);
XWPFRun para2Run = para2.createRun();
para2Run.setText(string2);
para2Run.setItalic(true);

XWPFParagraph para3 = document.createParagraph();
para3.setAlignment(ParagraphAlignment.LEFT);
String string3 = convertTextFileToString(paragraph3);
XWPFRun para3Run = para3.createRun();
para3Run.setText(string3);

Создание этих трех абзацев почти одинаково, за исключением некоторых стилей, таких как выравнивание или курсив.

4.4. Создание файла MS Word

Теперь мы готовы записать файл Microsoft Word в память из переменной документа :

FileOutputStream out = new FileOutputStream(output);
document.write(out);
out.close();
document.close();

Все фрагменты кода в этом разделе заключены в метод с именем handleSimpleDoc .

5. Разбор и тестирование

В этом разделе описывается разбор файлов MS Word и проверка результата.

5.1. Подготовка

Объявляем статическое поле в тестовом классе:

static WordDocument wordDocument;

Это поле используется для ссылки на экземпляр класса, который содержит все фрагменты кода, показанные в разделах 3 и 4.

Перед синтаксическим анализом и тестированием нам нужно инициализировать статическую переменную, объявленную выше, и сгенерировать файл rest-with-spring.docx в текущем рабочем каталоге, вызвав метод handleSimpleDoc :

@BeforeClass
public static void generateMSWordFile() throws Exception {
WordTest.wordDocument = new WordDocument();
wordDocument.handleSimpleDoc();
}

Переходим к завершающему этапу: разбору файла MS Word и проверке результата.

5.2. Разбор файла MS Word и проверка

Во-первых, мы извлекаем содержимое из данного файла MS Word в каталоге проекта и сохраняем содержимое в списке XWPFParagraph : ``

Path msWordPath = Paths.get(WordDocument.output);
XWPFDocument document = new XWPFDocument(Files.newInputStream(msWordPath));
List<XWPFParagraph> paragraphs = document.getParagraphs();
document.close();

Далее, давайте удостоверимся, что содержание и стиль заголовка такие же, как то, что мы установили ранее:

XWPFParagraph title = paragraphs.get(0);
XWPFRun titleRun = title.getRuns().get(0);

assertEquals("Build Your REST API with Spring", title.getText());
assertEquals("009933", titleRun.getColor());
assertTrue(titleRun.isBold());
assertEquals("Courier", titleRun.getFontFamily());
assertEquals(20, titleRun.getFontSize());

Для простоты мы просто проверяем содержимое других частей файла, исключая стили. Проверка их стилей аналогична тому, что мы сделали с заголовком:

assertEquals("from HTTP fundamentals to API Mastery",
paragraphs.get(1).getText());
assertEquals("What makes a good API?", paragraphs.get(3).getText());
assertEquals(wordDocument.convertTextFileToString
(WordDocument.paragraph1), paragraphs.get(4).getText());
assertEquals(wordDocument.convertTextFileToString
(WordDocument.paragraph2), paragraphs.get(5).getText());
assertEquals(wordDocument.convertTextFileToString
(WordDocument.paragraph3), paragraphs.get(6).getText());

Теперь мы можем быть уверены, что создание файла rest-with-spring.docx прошло успешно.

6. Заключение

В этом руководстве представлена поддержка Apache POI для формата Microsoft Word. Он прошел шаги, необходимые для создания файла MS Word и проверки его содержимого.

Реализацию всех этих примеров и фрагментов кода можно найти в проекте на GitHub .