Android点击按钮实现List转Excel无异常但文件未生成
问题现象
我参考了《Generate excel from android listview》一文的实现方案,计划将List数据转换为Excel表格,但点击触发按钮后该基础功能无法正常运行。
对应实现代码如下:
public void generateXL(View view) throws IOException { String Fnamexls="excelSheet"+System.currentTimeMillis()+ ".xls"; File fsd = Environment.getExternalStorageDirectory(); String filePath = Environment.getExternalStorageDirectory()+File.separator+"kmc"; File dir = context.getDir("mydir", Context.MODE_PRIVATE); if(!dir.isDirectory() || !dir.exists()){ dir.mkdirs(); } boolean b=dir.mkdir(); Toast.makeText(context, String.valueOf(b), Toast.LENGTH_SHORT).show(); File file = new File(dir, Fnamexls); WorkbookSettings wbSettings = new WorkbookSettings(); wbSettings.setLocale(new Locale("en", "EN")); WritableWorkbook workbook; try { int a = 1; workbook = Workbook.createWorkbook(file, wbSettings); //workbook.createSheet("Report", 0); WritableSheet sheet = workbook.createSheet("First Sheet", 0); Label label = new Label(0, 2, "SECOND"); Label label1 = new Label(0,1,"first"); Label label0 = new Label(0,0,"HEADING"); Label label3 = new Label(1,0,"Heading2"); Label label4 = new Label(1,1,String.valueOf(a)); try { sheet.addCell(label); sheet.addCell(label1); sheet.addCell(label0); sheet.addCell(label4); sheet.addCell(label3); } catch (RowsExceededException e) { e.printStackTrace(); } catch (WriteException e) { e.printStackTrace(); } workbook.write(); try { workbook.close(); } catch (WriteException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } Toast.makeText(this, dir.toString(), Toast.LENGTH_SHORT).show(); }
预期执行上述generateXL方法后可成功生成Excel文件输出,但实际运行过程中代码未抛出任何异常,目标Excel文件始终未被成功创建。
故障原因
- 路径混淆:代码中定义了外部存储路径变量
fsd、filePath但从未使用,实际文件写入路径是context.getDir("mydir", Context.MODE_PRIVATE)返回的应用私有目录,若去外部存储查找文件自然无法找到。 - 目录创建逻辑冗余:判断目录不存在时已经调用
dir.mkdirs()完成创建,后续重复调用dir.mkdir()必然返回false,虽不影响目录实际创建,但容易干扰判断。 - 缺少结果校验:写入流程结束后没有校验目标文件是否存在,无法快速定位是写入失败还是查找路径错误。
- 异常处理不完善:所有异常仅打印栈轨迹,没有在捕获异常时给出明确提示,出现写入失败时无感知。
修复方案
- 清理无效冗余变量,明确文件存储路径,避免路径混淆
- 优化目录创建逻辑,仅保留
mkdirs()递归创建目录,移除重复的mkdir()调用 - 写入完成后增加文件存在性校验,明确创建结果
- 统一在资源释放逻辑中关闭工作簿,避免资源泄漏
- 若需要将文件存储到外部公共目录,需按系统版本适配存储权限与分区存储规则
修复后的核心代码参考:
public void generateXL(View view) { String fileName = "excelSheet"+System.currentTimeMillis()+ ".xls"; // 此处使用应用私有目录,无需额外权限;若需存外部存储请自行做权限适配 File dir = new File(getFilesDir(), "excelDir"); if(!dir.exists()){ // mkdirs可递归创建多级目录,无需额外判断是否为目录 dir.mkdirs(); } File targetFile = new File(dir, fileName); WorkbookSettings wbSettings = new WorkbookSettings(); wbSettings.setLocale(new Locale("en", "EN")); WritableWorkbook workbook = null; try { workbook = Workbook.createWorkbook(targetFile, wbSettings); WritableSheet sheet = workbook.createSheet("First Sheet", 0); // 写入单元格内容 sheet.addCell(new Label(0,0,"HEADING")); sheet.addCell(new Label(1,0,"Heading2")); sheet.addCell(new Label(0,1,"first")); sheet.addCell(new Label(1,1,"1")); sheet.addCell(new Label(0,2,"SECOND")); workbook.write(); // 校验文件创建结果 if(targetFile.exists()){ Toast.makeText(this, "Excel创建成功,路径:"+targetFile.getAbsolutePath(), Toast.LENGTH_LONG).show(); }else{ Toast.makeText(this, "Excel创建失败", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "创建出错:"+e.getMessage(), Toast.LENGTH_SHORT).show(); }finally { // 统一在finally中关闭工作簿,避免资源泄漏 if(workbook != null){ try { workbook.close(); } catch (IOException | WriteException e) { e.printStackTrace(); } } } }
注意:应用私有目录下的文件无法被手机上的其他办公App直接访问,如果需要生成后让用户可以直接在文件管理器找到、用其他App打开,请将文件存储到公开目录,并做好对应版本的权限与分区存储适配。
内容的提问来源于stack exchange,提问作者Vikas Konaparthi
相关产品推荐
相关产品推荐

