使用Apache POI从Word文档中提取段落

时间:2018-02-01 07:25:20

标签: java apache

我有一个word文档 Docx file

正如您在单词文档中看到的那样,有一些关于子弹点的问题。现在我试图使用apache POI从文件中提取每个段落。这是我目前的代码

    public static String readDocxFile(String fileName) {
    try {
        File file = new File(fileName);
        FileInputStream fis = new FileInputStream(file.getAbsolutePath());
        XWPFDocument document = new XWPFDocument(fis);

        List<XWPFParagraph> paragraphs = document.getParagraphs();
        String whole = "";
        for (XWPFParagraph para : paragraphs) {
            System.out.println(para.getText());
            whole += "\n" + para.getText();
        }
        fis.close();
        document.close();
        return whole;
    } catch (Exception e) {
        e.printStackTrace();
        return "";
    }
    }

上述方法的问题在于它是打印每一行而不是段落。此外,子弹点也从提取的whole字符串中消失。 whole返回一个纯字符串。

任何人都可以解释我做错了什么。如果您有更好的解决方法,请提出建议。

2 个答案:

答案 0 :(得分:1)

上面的代码是正确的,我在我的系统上运行了代码,给出了每个段落,我认为只要我在子弹点上编写内容并使用&#39;输入&#39;关键比打破我当前的要点和上面的代码使得那个断线成为saparate段。

我正在编写下面的代码示例可能对您有用,请看这里我使用Set datastructure来忽略来自docx的重复问题。

apache poi的依赖性低于

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

代码示例:

package com;

import java.io.File;
import java.io.FileInputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.springframework.util.ObjectUtils;

public class App {

    public static void main(String...strings) throws Exception{
        Set<String> bulletPoints = fileExtractor(); 
        bulletPoints.forEach(point -> {
            System.out.println(point);
        });
    }

    public static Set<String> fileExtractor() throws Exception{
        FileInputStream fis = null;
        try {
            Set<String> bulletPoints = new HashSet<>();
            File file = new File("/home/deskuser/Documents/query.docx");
            fis = new FileInputStream(file.getAbsolutePath());
            XWPFDocument document = new XWPFDocument(fis);

            List<XWPFParagraph> paragraphs = document.getParagraphs();
            paragraphs.forEach(para -> {
                System.out.println(para.getText());
                if(!ObjectUtils.isEmpty(para.getText())){
                    bulletPoints.add(para.getText());
                }
            });
            fis.close();

            return bulletPoints;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("error while extracting file.", e);
        }finally{
            if(!ObjectUtils.isEmpty(fis)){
                fis.close();
            }
        }
    }
}

答案 1 :(得分:-1)

我找不到您正在使用的apache POI版本。如果它是最新版本(3.17),则代码中使用的XWPFParagraph对象具有getNumFmt()方法。从apache poi文档(https://poi.apache.org/apidocs/org/apache/poi/xwpf/usermodel/XWPFParagraph.html)开始,如果段落以项目符号开头,则此方法将返回字符串"bullet"。因此,关于问题的第二点(子弹会发生什么),您可以解决以下问题:

public class TestPoi {

    private static final String BULLET = "•";

    private static final String NEWLINE = "\n";

    public static void main(String...args) {
        String test = readDocxFile("/home/william/Downloads/anesthesia.docx");
        System.out.println(test);
    }

    public static String readDocxFile(String fileName) {
        try {
            File file = new File(fileName);
            FileInputStream fis = new FileInputStream(file.getAbsolutePath());
            XWPFDocument document = new XWPFDocument(fis);

            List<XWPFParagraph> paragraphs = document.getParagraphs();
            StringBuilder whole = new StringBuilder();
            for (XWPFParagraph para : paragraphs) {
                if ("bullet".equals(para.getNumFmt())) {
                    whole.append(BULLET);
                }
                whole.append(para.getText());
                whole.append(NEWLINE);
            }
            fis.close();
            document.close();
            return whole.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}

关于你的第一点,预期产量是多少?我使用提供的docx运行你的代码,除了你提到的丢失的子弹之外,它看起来还可以通过调试器来完成。