使用 Intent.ACITON_CREATE_DOCUMENT 将 Sqlite 数据库导出到 Excel 文件

Exporting Sqlite Database to Excel file using Intent.ACITON_CREATE_DOCUMENT

感谢程序员,我正在使用一个非常好的库,它使导出变得非常容易,但我担心的是因为 Android 10,文件无法导出到设备的内部存储器。该文件以包名称导出。不过没问题,我正在尝试的是,我想使用 Intent.ACTION_CREATE_DOCUMENT,并让用户选择保存从 Sqlite 数据库生成的 excel 文件的位置。
下面是将 sqlite 转换为 excel 的代码,它会在 Android < 10.

上转换并自动将其保存到内存中
public void exportDBtoExcel() {
        String folder;
        Context context = getApplicationContext();
        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Musajjal Report/";
        File externalFolder = context.getExternalFilesDir(null);
       
        folder = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Musajjal Report/" ;

        File file = new File(folder); // this below 2 lines of code is for Android > 10
        if (externalFolder != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
            folder = externalFolder.getAbsolutePath();
        }
        boolean fileCreated = file.exists();
        if ( !fileCreated ) {
            fileCreated = file.mkdirs();
        }
        if ( fileCreated ) {

            // Export SQLite DB as EXCEL FILE
            SQLiteToExcel sqliteToExcel = new SQLiteToExcel(getApplicationContext(), StudentDatabase.DBname,folder);
            sqliteToExcel.exportAllTables("Student.xls", new SQLiteToExcel.ExportListener() {
                @Override
                public void onStart() {

                }

                @Override
                public void onCompleted(String filePath) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                    builder.setTitle("Report Generated");
                    builder.setMessage(filePath);
                    builder.setCancelable(false);
                    builder.setPositiveButton("Ok", (dialogInterface, i) -> builder.setCancelable(true));
                    builder.show();
                }

                @Override
                public void onError(Exception e) {
                    Toast.makeText(getApplicationContext(), "Export Failed: " + e, Toast.LENGTH_LONG).show();

                }
            });

        }

    }  

我的问题是如何使用文件管理器保存excel文件,请帮忙,提前谢谢。我试过使用下面的代码但它似乎不起作用,因为在我可以使用文件管理器选择要保存的位置之前,上面的方法正在转换和保存。

private void createFile() {
        // when you create document, you need to add Intent.ACTION_CREATE_DOCUMENT
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        // filter to only show openable items.
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        // Create a file with the requested Mime type
        intent.setType("text/csv");

        startActivityForResult(intent, WRITE_REQ);
    }  

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == WRITE_REQ){
            switch (resultCode){
                case Activity
                        .RESULT_OK:
                    if (data != null && data.getData() != null){
                        exportDBtoExcel();
                    }
                    break;
                case Activity.RESULT_CANCELED:
                    break;
            }
        }
    }

我使用 JXL 库以这种方式解决了这个问题:

exportToExcel() 函数:

    private static final int CREATE_FILE_XLS = 2;

    private void exportToExcel() {
    final String fileName = "sample.xls";
    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("application/xls");
    intent.putExtra(Intent.EXTRA_TITLE, fileName);
    startActivityForResult(intent, CREATE_FILE_XLS);
    }

onActivityResult :

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent 
      resultData) 
    {
    super.onActivityResult(requestCode, resultCode, resultData);
    if (requestCode == CREATE_FILE_XLS && resultCode == Activity.RESULT_OK) {
        Uri uri = null;
        if (resultData != null) {
            uri = resultData.getData();
            try {
                WriteToExcelFile(uri);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (BiffException e) {
                e.printStackTrace();
            }
        }
    }

}

读取 Sqlite 数据库并写入 Exle 文件:

    public void WriteToExcelFile(Uri uri) throws IOException, BiffException {
        // Read database
        ArrayList<ReportModel> cursor = databaseHelper.getReports();
        OutputStream os = getContentResolver().openOutputStream(uri);
        WorkbookSettings wbSettings = new WorkbookSettings();
        wbSettings.setLocale(new Locale("fa", "FA"));
        WritableWorkbook workbook;
        try {
            workbook = Workbook.createWorkbook(os, wbSettings);
            WritableSheet sheet = workbook.createSheet("Features", 0);
            try {
                sheet.addCell(new jxl.write.Label(0, 0, "id"));
                sheet.addCell(new jxl.write.Label(1, 0, "name"));
                sheet.addCell(new jxl.write.Label(2, 0, "type"));
                int index = 3;
                int position = 1;
                index = 3;
                if (cursor != null) {
                    for (ReportModel data : cursor) {
                        sheet.addCell(new jxl.write.Label(0, position, data.getId() + ""));
                        sheet.addCell(new jxl.write.Label(1, position, data.getName() + ""));
                        sheet.addCell(new jxl.write.Label(2, position, data.getType() + ""));
                        position++;
                    }
                }
            } 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();
    }
}