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);
}
}
}
}
我的应用程序需要处理来自由文本组成的 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);
}
}
}
}