Traitement de Microsoft Word en Java avec Apache POI

1. Vue d'ensemble

Apache POI est une bibliothèque Java permettant de travailler avec les différents formats de fichiers basés sur les standards Office Open XML (OOXML) et le format de document composé OLE 2 de Microsoft (OLE2).

Ce didacticiel se concentre sur la prise en charge d'Apache POI pour 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 de Maven

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

 org.apache.poi poi-ooxml 3.15 

Veuillez cliquer ici pour la dernière version de cet artefact.

3. Préparation

Examinons maintenant certains des éléments utilisés pour faciliter la génération d'un fichier MS Word.

3.1. Fichiers de ressources

Nous collecterons le contenu de trois fichiers texte et les écrirons 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 classpath 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 donné dans la dernière section de ce tutoriel, est extrait de cette page de cours ici sur le site.

3.2. Méthode d'assistance

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

public String convertTextFileToString(String fileName) { try (Stream 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 String transmis . Ensuite, il concatène les lignes de ce fichier et renvoie la chaîne de jonction .

4. Génération de fichiers 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

Afin de 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 enveloppé 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 d'ensemble à partir de leurs noms.

De la même manière, nous créons une instance XWPFParagraph englobant le sous-titre:

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

Formalisons é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 donné ci-dessus:

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

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

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

Une image est extraite d'un fichier sur le 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. Formatage des paragraphes

Voici comment nous créons le premier paragraphe avec le contenu tiré 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 la même manière, 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 la même, à l'exception de certains styles tels que l'alignement ou l'italique.

4.4. Générer un fichier MS Word

Now we are ready to write out a Microsoft Word file to memory from the document variable:

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

All the code snippets in this section are wrapped in a method named handleSimpleDoc.

5. Parsing and Testing

This section outlines the parsing of MS Word files and verification of the result.

5.1. Preparation

We declare a static field in the test class:

static WordDocument wordDocument;

This field is used to reference to an instance of the class that encloses all the code fragments shown in sections 3 and 4.

Before parsing and testing, we need to initialize the static variable declared right above and generate the rest-with-spring.docx file in the current working directory by invoking the handleSimpleDoc method:

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

Let's move on to the final step: parsing the MS Word file and the verification of the outcome.

5.2. Parsing MS Word File and Verification

First, we extract contents from the given MS Word file in the project directory and the store the contents in a List of XWPFParagraph:

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

Next, let's make sure that the content and style of the title is the same as what we have set before:

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

For the sake of simplicity, we just validate the contents of other parts of the file, leaving out the styles. The verification of their styles is similar to what we have done with the title:

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

Now we can be confident that the creation of the rest-with-spring.docx file has been successful.

6. Conclusion

Ce didacticiel a présenté la prise en charge des POI Apache pour le format Microsoft Word. Il est passé par les étapes nécessaires pour générer un fichier MS Word et pour vérifier son contenu.

L'implémentation de tous ces exemples et extraits de code peut être trouvée dans un projet GitHub.