Microsoft Word Processing in Java con Apache POI

1. Panoramica

Apache POI è una libreria Java per lavorare con i vari formati di file basati sugli standard Office Open XML (OOXML) e sul formato OLE 2 Compound Document di Microsoft (OLE2).

Questo tutorial si concentra sul supporto di Apache POI per Microsoft Word, il formato di file di Office più comunemente utilizzato. Esegue i passaggi necessari per formattare e generare un file MS Word e come analizzare questo file.

2. Dipendenze di Maven

L'unica dipendenza richiesta per Apache POI per gestire i file MS Word è:

 org.apache.poi poi-ooxml 3.15 

Fare clic qui per l'ultima versione di questo artefatto.

3. Preparazione

Vediamo ora alcuni degli elementi utilizzati per facilitare la generazione di un file MS Word.

3.1. File di risorse

Raccoglieremo il contenuto di tre file di testo e li scriveremo in un file MS Word, chiamato rest-with-spring.docx .

Inoltre, il file logo-leaf.png viene utilizzato per inserire un'immagine in quel nuovo file. Tutti questi file esistono sul classpath e sono rappresentati da diverse variabili statiche:

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

Per i curiosi, i contenuti di questi file di risorse nel repository, il cui link è riportato nell'ultima sezione di questo tutorial, sono estratti da questa pagina del corso qui sul sito.

3.2. Metodo di aiuto

Il metodo principale costituito dalla logica utilizzata per generare un file MS Word, descritto nella sezione seguente, utilizza un metodo di supporto:

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

Questo metodo estrae il contenuto contenuto in un file di testo situato nel classpath, il cui nome è l' argomento String passato . Quindi, concatena le righe in questo file e restituisce la stringa di unione .

4. Generazione di file MS Word

Questa sezione fornisce istruzioni su come formattare e generare un file Microsoft Word. Prima di lavorare su qualsiasi parte del file, abbiamo bisogno di un'istanza XWPFDocument :

XWPFDocument document = new XWPFDocument();

4.1. Formattazione di titolo e sottotitolo

Per creare il titolo, dobbiamo prima istanziare la classe XWPFParagraph e impostare l'allineamento sul nuovo oggetto:

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

Il contenuto di un paragrafo deve essere racchiuso in un oggetto XWPFRun . Possiamo configurare questo oggetto per impostare un valore di testo e i suoi stili associati:

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

Si dovrebbe essere in grado di dedurre gli scopi dei metodi set dai loro nomi.

In modo simile creiamo un'istanza XWPFParagraph che racchiude il sottotitolo:

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

Formattiamo anche il sottotitolo:

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

Il metodo setTextPosition imposta la distanza tra il sottotitolo e l'immagine successiva, mentre setUnderline determina il motivo di sottolineatura.

Si noti che codifichiamo il contenuto sia del titolo che del sottotitolo poiché queste istruzioni sono troppo brevi per giustificare l'uso di un metodo di supporto.

4.2. Inserimento di un'immagine

Un'immagine deve anche essere racchiusa in un'istanza XWPFParagraph . Vogliamo che l'immagine sia centrata orizzontalmente e posizionata sotto il sottotitolo, quindi il seguente frammento deve essere inserito sotto il codice dato sopra:

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

Here is how to set the distance between this image and the text below it:

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

An image is taken from a file on the classpath and then inserted into the MS Word file with the specified dimensions:

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. Formatting Paragraphs

Here is how we create the first paragraph with contents taken from the poi-word-para1.txt file:

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

It is apparent that the creation of a paragraph is similar to the creation of the title or subtitle. The only difference here is the use of the helper method instead of hard-coded strings.

In a similar way, we can create two other paragraphs using contents from files poi-word-para2.txt and 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);

The creation of these three paragraphs is almost the same, except for some styling such as alignment or italics.

4.4. Generating MS Word File

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

Questo tutorial ha introdotto il supporto dei POI di Apache per il formato Microsoft Word. Ha eseguito i passaggi necessari per generare un file MS Word e per verificarne il contenuto.

L'implementazione di tutti questi esempi e frammenti di codice può essere trovata in un progetto GitHub.