【问题标题】:PDFBox in Android or other means to extract text from PDF on device?Android中的PDFBox或其他从设备上的PDF中提取文本的方法?
【发布时间】:2020-09-10 03:51:38
【问题描述】:

我的应用需要处理来自包含文本的 PDF 文件的输入(大部分)。我可以在我的服务器上进行解析,但我不想这样做。无论如何,在探索了我的文本提取选项后,我发现了 PDFBox 库及其与 Android 一起使用的端口 (https://github.com/TomRoush/PdfBox-Android)

在应用程序中,我向用户展示了一个标准 UI,用于通过 ACTION_OPEN_DOCUMENT 选择源文档。然后覆盖 onActivityResult 以获取 Uri - 你知道的,通常的东西。

问题是我不知道如何将它提供给 PDFBox。因为我们不是在谈论“文件”,而是在谈论“文档”,所以 lib 需要一个真实的文件路径。如果我为某个文件提供它,文本解析就可以了,但这肯定不是最佳实践,而且它不能对所有文档(云存储等)都完成,所以我这样做:

InputStream inputStream = getContentResolver().openInputStream(uri);

然后逐行阅读,最后我可以将所有内容都放在一个字符串中。显然,它工作正常。

但是如何将这些数据实际输入 PDFBox 以发挥其文本提取的魔力呢?当我没有“真实文件路径”时,我找不到任何关于如何在场景中执行此操作的文档。

也许现在有更好的方法?这个库很老了。基本上我需要从 PDF 中提取文本并在 Android 设备上进行,而不是通过 API 调用。真的卡在这里了。

【问题讨论】:

  • 我真的不明白为什么你需要一个 Android 端口,对于不需要移植的东西。而且无法逐行读取二进制文件,因为它们没有行。也没有魔法……
  • @MikeM。查看“stripText”的示例代码部分
  • @galloper 是的,这表明File 不是必需的。注意他们是如何直接从从AssetManager 获得的InputStream 加载PDDocument
  • @MartinZeitler 相信我它确实需要移植,否则移植版本不会出现。在转向这个之前,我尝试使用原版。我知道我可以读取流然后另存为文件,我希望避免它

标签: java android pdfbox


【解决方案1】:

我的应用程序需要类似的功能,所以我尝试了 Mike M. 在 cmets 中根据您的问题提出的解决方案,它对我来说效果很好(所以这真的是他的回答 - 我只是确认它有效并提供了代码)。 希望对您有所帮助。

“魔力”其实就在这两行:

InputStream inputStream = this.getContentResolver().openInputStream(fileUri);
document = PDDocument.load(inputStream);

但是对于某些上下文(以及那些将在另一个场合搜索此问题的答案的人),这里是完整的示例代码:

public class MainActivity extends AppCompatActivity {

    private static final int OPEN_FILE_REQUEST_CODE = 1;
    Intent intentOpenfile;
    Uri fileUri;

    TextView tvTextDisplay;
    Button bOpenFile;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvTextDisplay = findViewById(R.id.tv_text_display);

        PDFBoxResourceLoader.init(getApplicationContext());

        bOpenFile = findViewById(R.id.b_open_file);
        bOpenFile.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                intentOpenfile = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intentOpenfile.setType("application/pdf");
                startActivityForResult(intentOpenfile, OPEN_FILE_REQUEST_CODE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == OPEN_FILE_REQUEST_CODE) {
            if(resultCode == RESULT_OK) {
                fileUri = data.getData();
                PDDocument document = null;
                String parsedText = null;
                try {
                    InputStream inputStream = this.getContentResolver().openInputStream(fileUri);
                    document = PDDocument.load(inputStream);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                try {
                    PDFTextStripper pdfStripper = new PDFTextStripper();
                    pdfStripper.setStartPage(0);
                    pdfStripper.setEndPage(1);
                    parsedText = "Parsed text: " + pdfStripper.getText(document);
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        if (document != null) document.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                tvTextDisplay.setText(parsedText);

            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 2017-03-24
    • 2014-07-11
    • 2013-11-15
    相关资源
    最近更新 更多