【问题标题】:Extract Paragraph from Word Document Using Apache POI使用 Apache POI 从 Word 文档中提取段落
【发布时间】:2018-02-01 07:25:20
【问题描述】:

我有一个word文档 Docx file

正如您在 word 文档中看到的那样,有许多关于要点的问题。现在我正在尝试使用 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 返回一个纯字符串。

谁能解释我做错了什么。如果您有更好的解决方法,请提出建议。

【问题讨论】:

  • 你想要达到的最终结果是什么?
  • @hovanessyan 我试图将每个段落或问题作为一个单独的字符串。所以基本上我试图将此 docx 文件转换为一个字符串数组,其中每个字符串都是一个段落。
  • 可能有多种方法可以实现最终结果——这就是为什么我要问想要的结果是什么。您正在编写一个程序来解决问题,而不是拥有一个充满字符串的数组 - 您要解决的问题是什么?
  • 您在类路径/项目中引用了哪个版本的 Apache POI?

标签: java apache


【解决方案1】:

上面的代码是正确的,我在我的系统上运行了你的代码,给出了每一个段落,我认为每当我在项目符号点中编写内容并使用“输入”键时,在 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();
            }
        }
    }
}

【讨论】:

  • 感谢您的回答。我已经尝试过了,但它和我上面的代码一样。您是否尝试过使用提供的文件进行测试?
  • 我已经为您提供的文件代码测试了代码,按照 apache poi 设计的代码工作正常,但是如果您想将每个问题连同他们的答案分开,而不是在编写您的问题时对您的文档进行一些更改和阅读时使用程序回答而不是saprate。
【解决方案2】:

我找不到您使用的 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 运行了您的代码,除了您提到的缺少的项目符号外,使用调试器单步执行看起来还不错。

【讨论】:

    猜你喜欢
    • 2016-10-02
    • 2022-01-19
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    相关资源
    最近更新 更多