2

I am using Apache POI to create a .docx file with the following code:

XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText(text);
String filePath = outputPathWithoutExtension + ".docx";
try {
    FileOutputStream stream = new FileOutputStream(new File(filePath));
    document.write(stream);
    stream.close();
} catch (IOException exception) {
    LOGGER.error("Could not create file '{}'", filePath);
}

and then I try to read it with the following code:

FileInputStream fileStream = new FileInputStream(filePath);
try {
    XWPFDocument docx = new XWPFDocument(fileStream);
    XWPFWordExtractor wordExtractor = new XWPFWordExtractor(docx);
    text = wordExtractor.getText();
} catch (IOException | POIXMLException | OfficeXmlFileException
            | NullPointerException exception) {
     LOGGER.error("Could not load file - Exception: {}", exception.getMessage());
}

On the line where I call getText(), it is throwing a NullPointerException:

java.lang.NullPointerException
at org.apache.poi.xwpf.extractor.XWPFWordExtractor.extractHeaders(XWPFWordExtractor.java:162)
at org.apache.poi.xwpf.extractor.XWPFWordExtractor.getText(XWPFWordExtractor.java:87)

The issue appears to be that extractText calls extractHeaders with the XWPFHeaderFooterPolicy of the document ... which in my case is null. When it tries to use it on its very first line ... boom.

I tried to create my own "header/footer policy" like so:

try {
    new XWPFHeaderFooterPolicy(document);
} catch (IOException | XmlException exception) {
    LOGGER.warn("Could not create output document header - "
           + "document might not be readable in all readers");
}

However, that itself throws a NullPointerException because it tries to access the "SectPr" of the document via doc.getDocument().getBody().getSectPr(), which returns null ... and then the first time it uses that ... boom.

So, my question is: I'm clearly not creating the XWPFDocument correctly ... could someone set me straight?

Side note: If I open the file in Word, the file looks fine. If between the creation and reading of the file, I open it, edit it, save it, and close it, then the call to getText() executes as expected with no NullPointerException. Word must fill in the appropriate header/footer policy on save.

Eric
  • 1,414
  • 3
  • 16
  • 35
  • Looks to be a bug - did you try reporting it as a bug to [the Apache POI bug tracker](https://bz.apache.org/bugzilla/enter_bug.cgi?product=POI)? – Gagravarr Oct 20 '15 at 19:39

2 Answers2

1

Aha! I found my answer here: How to create a header/footer in new docx document?

I basically just gave up one step too soon. Adding this code to the creation of the document allowed it to be read:

// Add a SectPr and header/footer policy so document can be opened and read by POI
try {
    document.getDocument().getBody().addNewSectPr();
    new XWPFHeaderFooterPolicy(document);
} catch (IOException | XmlException exception) {
    LOGGER.warn("Could not create output document header - "
            + "document might not be readable in all readers");
}
Community
  • 1
  • 1
Eric
  • 1,414
  • 3
  • 16
  • 35
0
    //---------------------Modify Footer or Headder change footer x headder 
//If you need some help tell me. agustinoscarmendez@gmail.com
try {
            XWPFDocument doc = new XWPFDocument(OPCPackage.open("C:\\Users\\amendez\\Documents\\NetBeansProjects\\PuertasSRL_Presupuesto\\Resources\\Words y Excel Examples\\Modelos de EPC.docx"));
            //XWPFDocument doc = new XWPFDocument();
            CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
            XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(doc, sectPr);
            XWPFHeaderFooterPolicy hfp = doc.getHeaderFooterPolicy();
            //XWPFFooter ffffff = hfp.getFooter(1); //Para cambiar el footer de la primera pagina
            XWPFFooter ffffff = hfp.getDefaultFooter();//to change all pages
            for (XWPFParagraph p : ffffff.getParagraphs()) {
            List<XWPFRun> runs = p.getRuns();
            if (runs != null) {
                for (XWPFRun r : runs) {
                    String text = r.getText(0);
                    if (text != null && text.contains("VPALABRA")) { //if the text contains the word you want to change
                        text = text.replace("VPALABRA", "twitter: GugaMendez"); //change the  word to the new word
                        r.setText(text, 0);
                    }
                }
            }
        }
FileOutputStream out = new FileOutputStream("C:\\Users\\amendez\\Desktop\\Agustín\\carpetas\\write-test4.docx");
                    doc.write(out);
                    out.close();
                    System.out.println("Done perro");
        } catch (Exception ex) {
           ex.printStackTrace();
Guga
  • 1