Traitement de Microsoft Word en Java avec POI Apache

1. Vue d’ensemble

Apache POI est une bibliothèque Java permettant de travailler avec divers formats de fichiers basés sur les standards Office Open XML (OOXML) et le format OLE 2 (Microsoft Oound 2 Compound Document) de Microsoft.

Ce tutoriel porte sur la prise en charge de Apache POI for Microsoft Word , le format de fichier Office le plus couramment utilisé. Il décrit les étapes nécessaires pour formater et générer un fichier MS Word et comment analyser ce fichier.

2. Dépendances Maven

La seule dépendance requise pour que les POI Apache puissent gérer les fichiers MS Word est:

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

3. Préparation

Voyons maintenant quelques-uns des éléments utilisés pour faciliter la génération d’un fichier MS Word.

3.1. Fichiers de ressources

Nous allons collecter le contenu de trois fichiers texte et les écrire dans un fichier MS Word nommé rest-with-spring.docx .

De plus, le fichier logo-leaf.png est utilisé pour insérer une image dans ce nouveau fichier. Tous ces fichiers existent sur le chemin de classe et sont représentés par plusieurs variables statiques:

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

Pour les curieux, le contenu de ces fichiers de ressources dans le référentiel, dont le lien est indiqué dans la dernière section de ce didacticiel, est extrait du lien:/rest-with-spring-course? Utm__source = blog

3.2. Méthode d’assistance

La méthode principale consistant en une logique utilisée pour générer un fichier MS Word, décrite dans la section suivante, utilise une méthode d’assistance:

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

Cette méthode extrait le contenu contenu dans un fichier texte situé sur le chemin de classe, dont le nom est l’argument transmis String . Ensuite, il concatène des lignes dans ce fichier et retourne le String joint.

4. Génération de fichier MS Word

Cette section explique comment formater et générer un fichier Microsoft Word. Avant de travailler sur une partie du fichier, nous devons avoir une instance XWPFDocument :

XWPFDocument document = new XWPFDocument();

4.1. Formatage du titre et du sous-titre

Pour créer le titre, nous devons d’abord instancier la classe XWPFParagraph et définir l’alignement sur le nouvel objet:

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

Le contenu d’un paragraphe doit être encapsulé dans un objet XWPFRun .

Nous pouvons configurer cet objet pour définir une valeur de texte et ses styles associés:

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

On devrait pouvoir déduire les buts des méthodes set à partir de leurs noms.

De manière similaire, nous créons une instance de XWPFParagraph contenant le sous-titre:

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

Formateons également le sous-titre:

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

La méthode setTextPosition définit la distance entre le sous-titre et l’image suivante, tandis que setUnderline détermine le motif de soulignement.

Notez que nous codons en dur le contenu du titre et du sous-titre car ces instructions sont trop courtes pour justifier l’utilisation d’une méthode d’assistance.

4.2. Insérer une image

Une image doit également être encapsulée dans une instance XWPFParagraph . Nous voulons que l’image soit centrée horizontalement et placée sous le sous-titre, ainsi l’extrait suivant doit être placé sous le code indiqué ci-dessus:

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

Voici comment définir la distance entre cette image et le texte situé en dessous:

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

Une image est extraite d’un fichier du chemin de classe, puis insérée dans le fichier MS Word avec les dimensions spécifiées:

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. Mise en forme des paragraphes

Voici comment nous créons le premier paragraphe avec le contenu extrait du fichier poi-word-para1.txt :

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

Il est évident que la création d’un paragraphe est similaire à la création du titre ou du sous-titre. La seule différence ici est l’utilisation de la méthode d’assistance au lieu de chaînes codées en dur.

De manière similaire, nous pouvons créer deux autres paragraphes en utilisant le contenu des fichiers poi-word-para2.txt et 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);

La création de ces trois paragraphes est presque identique, à l’exception de certains styles tels que l’alignement ou l’italique.

4.4. Générer un fichier MS Word

Nous sommes maintenant prêts à écrire un fichier Microsoft Word en mémoire à partir de la variable document :

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

Tous les extraits de code de cette section sont encapsulés dans une méthode nommée handleSimpleDoc .

5. Analyse et test

Cette section décrit l’analyse des fichiers MS Word et la vérification du résultat.

5.1. Préparation

Nous déclarons un champ statique dans la classe de test:

static WordDocument wordDocument;

Ce champ est utilisé pour faire référence à une instance de la classe qui englobe tous les fragments de code présentés dans les sections 3 et 4.

Avant d’analyser et de tester, nous devons initialiser la variable statique déclarée juste ci-dessus et générer le fichier rest-with-spring.docx dans le répertoire de travail en cours en appelant la méthode handleSimpleDoc :

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

Passons à l’étape finale: l’analyse du fichier MS Word et la vérification du résultat.

5.2. Analyse de fichier MS Word et vérification

Premièrement, nous extrayons le contenu du fichier MS Word donné dans le répertoire du projet et le stockons dans un List de XWPFParagraph :

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

Ensuite, vérifions que le contenu et le style du titre sont les mêmes que ceux que nous avons définis auparavant:

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

Par souci de simplicité, nous validons simplement le contenu des autres parties du fichier, en omettant les styles. La vérification de leurs styles est similaire à ce que nous avons fait avec le titre:

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

Nous pouvons maintenant être certains que la création du fichier rest-with-spring.docx a été une réussite.

6. Conclusion

Ce tutoriel présente le support Apache POI pour le format Microsoft Word. Il a suivi les étapes nécessaires pour générer un fichier MS Word et en vérifier le contenu.

Vous trouverez la mise en œuvre de tous ces exemples et extraits de code dans a projet GitHub .