Android 中的 PDFBox 或其他从设备上的 PDF 中提取文本的方法?

PDFBox in Android or other means to extract text from PDF on device?

我的应用程序需要处理来自由文本组成的 PDF 文件的输入(大部分)。我可以在我的服务器上进行解析,但我不想这样做。无论如何,在探索了我的文本提取选项之后,我找到了 PDFBox 库及其与 Android (https://github.com/TomRoush/PdfBox-Android)

一起使用的端口

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

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

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

然后逐行阅读,最后我可以把它全部放在一个字符串中。显然,它工作正常。

但是如何将这些数据实际输入到 PDFBox 中以发挥其文本提取的魔力?当我没有 "real file path".

时,我找不到任何关于如何在场景中执行此操作的文档

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

我的应用程序需要类似的功能,所以我尝试了 Mike M. 在你的问题下的评论中建议的解决方案,它对我来说非常有用(所以这真的是他的回答——我只是确认它有效并提供代码)。 希望对你有帮助。

真正的“魔力”就在于这两行:

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

            }
        }
    }
}