Android Studio使用POI读取Excel文件仅提示请选择Excel文件如何解决?
问题根源
你触发错误的核心原因是onActivityResult中对Uri的处理逻辑错误:
使用Intent.ACTION_OPEN_DOCUMENT调用系统文件选择器返回的是content://格式的Uri,调用data.getData().getPath()拿到的是系统提供的虚拟路径(格式类似/document/xxxx),并非真实磁盘路径,不会携带.xlsx/.xls后缀,所以后缀判断必然失败走else分支。
修复步骤
- 第一步:修改文件选择器配置,从源头仅允许选择Excel文件
修改selectfile方法代码:
private void selectfile() { // 从文件存储选择文件 Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); // 指定仅展示Excel类型文件 intent.setType("application/vnd.ms-excel|application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(Intent.createChooser(intent, "选择文件"), 102); }
- 第二步:重写
onActivityResult的文件校验逻辑
不要直接读取Uri的路径判断后缀,改为通过ContentResolver查询文件MIME类型或真实文件名做校验:
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 102) { if (resultCode == RESULT_OK && data != null) { Uri fileUri = data.getData(); boolean isExcelFile = false; // 优先通过MIME类型判断 String mimeType = getContentResolver().getType(fileUri); if (mimeType != null) { isExcelFile = mimeType.equals("application/vnd.ms-excel") || mimeType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); } // MIME类型获取失败则查询文件名判断后缀 if (!isExcelFile) { Cursor cursor = getContentResolver().query(fileUri, null, null, null, null); if (cursor != null && cursor.moveToFirst()) { int nameColumnIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); String fileName = cursor.getString(nameColumnIndex); isExcelFile = fileName.endsWith(".xlsx") || fileName.endsWith(".xls"); cursor.close(); } } if (isExcelFile) { Toast.makeText(this, "Yesssss", Toast.LENGTH_SHORT).show(); readFile(fileUri); } else { Toast.makeText(this, "请选择Excel文件!", Toast.LENGTH_SHORT).show(); } } } }
- 第三步:权限适配补充
如果你的应用targetSdkVersion≥33(Android 13及以上),READ_EXTERNAL_STORAGE权限已经失效,无需申请,直接使用ACTION_OPEN_DOCUMENT就可以正常读取选中的文件。
内容的提问来源于stack exchange,提问作者user16783181
相关产品推荐
相关产品推荐

