Microsoft Word Processing в Java с Apache POI

1. Обзор

Apache POI - это библиотека Java для работы с различными форматами файлов на основе стандартов Office Open XML (OOXML) и формата Microsoft OLE 2 Compound Document (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>

Пожалуйста, нажмите here для последней версия этого артефакта.

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";

Для тех, кому интересно, содержимое этих файлов ресурсов в репозитории, чья ссылка приведена в последнем разделе этого урока, извлечено из ссылки:/rest-with-spring-course? Utm__source = blog

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 . Затем он объединяет строки в этом файле и возвращает присоединяющуюся 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 в память из переменной document :

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 в каталоге проекта и сохраняем содержимое в List из 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 и проверки его содержимого.

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