1. 概要

Apache POI は、Office Open XML標準(OOXML)およびMicrosoftのOLE 2複合ドキュメント形式(OLE2)に基づくさまざまなファイル形式を処理するためのJavaライブラリです。

このチュートリアルでは、最も一般的に使用されるOfficeファイル形式である Apache POI for MicrosoftWordのサポートに焦点を当てています。 MS Wordファイルのフォーマットと生成に必要な手順と、このファイルの解析方法について説明します。

2. Mavenの依存関係

ApachePOIがMSWordファイルを処理するために必要な唯一の依存関係は次のとおりです。

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

このアーティファクトの最新バージョンについては、ここをクリックしてください。

3. 準備

次に、MSWordファイルの生成を容易にするために使用される要素のいくつかを見てみましょう。

3.1. リソースファイル

3つのテキストファイルの内容を収集し、 rest-with- spring.docxという名前のMSWordファイルに書き込みます。

さらに、 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. ヘルパーメソッド

次のセクションで説明するMSWordファイルの生成に使用されるロジックで構成されるメインメソッドは、ヘルパーメソッドを使用します。

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. MSWordファイルの生成

このセクションでは、MicrosoftWordファイルをフォーマットおよび生成する方法について説明します。 ファイルのいずれかの部分で作業する前に、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-methodsの目的を推測できるはずです。

同様の方法で、サブタイトルを囲む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);

クラスパス上のファイルから画像が取得され、指定されたサイズでMSWordファイルに挿入されます。

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のコンテンツを使用して、他の2つの段落を作成できます。

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

これらの3つの段落の作成は、配置や斜体などのスタイルを除いて、ほとんど同じです。

4.4. MSWordファイルの生成

これで、document変数からMicrosoftWordファイルをメモリに書き出す準備ができました。

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

このセクションのすべてのコードスニペットは、handleSimpleDocという名前のメソッドでラップされています。

5. 解析とテスト

このセクションでは、MSWordファイルの解析と結果の検証について概説します。

5.1. 準備

テストクラスで静的フィールドを宣言します。

static WordDocument wordDocument;

このフィールドは、セクション3および4に示されているすべてのコードフラグメントを囲むクラスのインスタンスを参照するために使用されます。

解析とテストを行う前に、すぐ上で宣言された静的変数を初期化し、 handleSimpleDoc メソッドを呼び出して、現在の作業ディレクトリにrest-with-spring.docxファイルを生成する必要があります。

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

最後のステップであるMSWordファイルの解析と結果の検証に移りましょう。

5.2. MSWordファイルの解析と検証

まず、プロジェクトディレクトリ内の指定されたMS Wordファイルからコンテンツを抽出し、そのコンテンツをXWPFParagraphListに保存します。

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. 結論

このチュートリアルでは、MicrosoftWord形式のApachePOIサポートを紹介しました。 MS Wordファイルを生成し、その内容を確認するために必要な手順を実行しました。

これらすべての例とコードスニペットの実装は、GitHubプロジェクトにあります。