Exportación de la base de datos SQLite al archivo csv en Android

Estoy tratando de exportar datos SQLite a la tarjeta SD en Android como un archivo CSV en un directorio.

Así que probé este método a continuación y aparentemente solo muestra este texto impreso:

PRIMERA TABLA DE LA BASE DE DATOS
FECHA, ARTÍCULO, MONTO, MONEDA

En mi DBHelper.java he definido la función de la siguiente manera:

public boolean exportDatabase() { DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault()); /**First of all we check if the external storage of the device is available for writing. * Remember that the external storage is not necessarily the sd card. Very often it is * the device storage. */ String state = Environment.getExternalStorageState(); if (!Environment.MEDIA_MOUNTED.equals(state)) { return false; } else { //We use the Download directory for saving our .csv file. File exportDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); if (!exportDir.exists()) { exportDir.mkdirs(); } File file; PrintWriter printWriter = null; try { file = new File(exportDir, "MyCSVFile.csv"); file.createNewFile(); printWriter = new PrintWriter(new FileWriter(file)); /**This is our database connector class that reads the data from the database. * The code of this class is omitted for brevity. */ SQLiteDatabase db = this.getReadableDatabase(); //open the database for reading /**Let's read the first table of the database. * getFirstTable() is a method in our DBCOurDatabaseConnector class which retrieves a Cursor * containing all records of the table (all fields). * The code of this class is omitted for brevity. */ Cursor curCSV = db.rawQuery("select * from contacts", null); //Write the name of the table and the name of the columns (comma separated values) in the .csv file. printWriter.println("FIRST TABLE OF THE DATABASE"); printWriter.println("DATE,ITEM,AMOUNT,CURRENCY"); while(curCSV.moveToNext()) { Long date = curCSV.getLong(curCSV.getColumnIndex("date")); String title = curCSV.getString(curCSV.getColumnIndex("title")); Float amount = curCSV.getFloat(curCSV.getColumnIndex("amount")); String description = curCSV.getString(curCSV.getColumnIndex("description")); /**Create the line to write in the .csv file. * We need a String where values are comma separated. * The field date (Long) is formatted in a readable text. The amount field * is converted into String. */ String record = df.format(new Date(date)) + "," + title + "," + amount + "," + description; printWriter.println(record); //write the record in the .csv file } curCSV.close(); db.close(); } catch(Exception exc) { //if there are any exceptions, return false return false; } finally { if(printWriter != null) printWriter.close(); } //If there are no errors, return true. return true; } } } 

Y mis columnas son:

  public static final String DATABASE_NAME = "MyDBName.db"; public static final String CONTACTS_TABLE_NAME = "contacts"; public static final String CONTACTS_COLUMN_ID = "id"; public static final String CONTACTS_COLUMN_TITLE = "title"; public static final String CONTACTS_COLUMN_AMOUNT = "amount"; public static final String CONTACTS_COLUMN_DESC = "description"; 

Avíseme si necesita más código.

Gracias por sus sugerencias chicos que me llevaron a esta respuesta:

 private void exportDB() { DBHelper dbhelper = new DBHelper(getApplicationContext()); File exportDir = new File(Environment.getExternalStorageDirectory(), ""); if (!exportDir.exists()) { exportDir.mkdirs(); } File file = new File(exportDir, "csvname.csv"); try { file.createNewFile(); CSVWriter csvWrite = new CSVWriter(new FileWriter(file)); SQLiteDatabase db = dbhelper.getReadableDatabase(); Cursor curCSV = db.rawQuery("SELECT * FROM contacts",null); csvWrite.writeNext(curCSV.getColumnNames()); while(curCSV.moveToNext()) { //Which column you want to exprort String arrStr[] ={curCSV.getString(0),curCSV.getString(1), curCSV.getString(2)}; csvWrite.writeNext(arrStr); } csvWrite.close(); curCSV.close(); } catch(Exception sqlEx) { Log.e("MainActivity", sqlEx.getMessage(), sqlEx); } } 

En caso de que alguien todavía tropiece con esta pregunta, publicaré mi solución, que es un poco más general que la aceptada. Debería poder exportar todas las tablas en una base de datos sqlite casi copiando las dos clases a continuación. Solo otros cambios necesarios deberían estar relacionados con obtener el contexto de la aplicación e importar csv abierto.

Algunas partes son prácticamente copiar y pegar desde otros subprocesos de stackoverflow, pero ya no pude encontrarlos.

Exportador Sqlite:

 import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import com.opencsv.CSVWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Can export an sqlite databse into a csv file. * * The file has on the top dbVersion and on top of each table data the name of the table * * Inspired by * https://stackoverflow.com/questions/31367270/exporting-sqlite-database-to-csv-file-in-android * and some other SO threads as well. * */ public class SqliteExporter { private static final String TAG = SqliteExporter.class.getSimpleName(); public static final String DB_BACKUP_DB_VERSION_KEY = "dbVersion"; public static final String DB_BACKUP_TABLE_NAME = "table"; public static String export(SQLiteDatabase db) throws IOException{ if( !FileUtils.isExternalStorageWritable() ){ throw new IOException("Cannot write to external storage"); } File backupDir = FileUtils.createDirIfNotExist(FileUtils.getAppDir() + "/backup"); String fileName = createBackupFileName(); File backupFile = new File(backupDir, fileName); boolean success = backupFile.createNewFile(); if(!success){ throw new IOException("Failed to create the backup file"); } List tables = getTablesOnDataBase(db); Log.d(TAG, "Started to fill the backup file in " + backupFile.getAbsolutePath()); long starTime = System.currentTimeMillis(); writeCsv(backupFile, db, tables); long endTime = System.currentTimeMillis(); Log.d(TAG, "Creating backup took " + (endTime - starTime) + "ms."); return backupFile.getAbsolutePath(); } private static String createBackupFileName(){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HHmm"); return "db_backup_" + sdf.format(new Date()) + ".csv"; } /** * Get all the table names we have in db * * @param db * @return */ public static List getTablesOnDataBase(SQLiteDatabase db){ Cursor c = null; List tables = new ArrayList<>(); try{ c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null); if (c.moveToFirst()) { while ( !c.isAfterLast() ) { tables.add(c.getString(0)); c.moveToNext(); } } } catch(Exception throwable){ Log.e(TAG, "Could not get the table names from db", throwable); } finally{ if(c!=null) c.close(); } return tables; } private static void writeCsv(File backupFile, SQLiteDatabase db, List tables){ CSVWriter csvWrite = null; Cursor curCSV = null; try { csvWrite = new CSVWriter(new FileWriter(backupFile)); writeSingleValue(csvWrite, DB_BACKUP_DB_VERSION_KEY + "=" + db.getVersion()); for(String table: tables){ writeSingleValue(csvWrite, DB_BACKUP_TABLE_NAME + "=" + table); curCSV = db.rawQuery("SELECT * FROM " + table,null); csvWrite.writeNext(curCSV.getColumnNames()); while(curCSV.moveToNext()) { int columns = curCSV.getColumnCount(); String[] columnArr = new String[columns]; for( int i = 0; i < columns; i++){ columnArr[i] = curCSV.getString(i); } csvWrite.writeNext(columnArr); } } } catch(Exception sqlEx) { Log.e(TAG, sqlEx.getMessage(), sqlEx); }finally { if(csvWrite != null){ try { csvWrite.close(); } catch (IOException e) { e.printStackTrace(); } } if( curCSV != null ){ curCSV.close(); } } } private static void writeSingleValue(CSVWriter writer, String value){ writer.writeNext(new String[]{value}); } } 

FileUtils :

 public class FileUtils { public static String getAppDir(){ return App.getContext().getExternalFilesDir(null) + "/" + App.getContext().getString(R.string.app_name); } public static File createDirIfNotExist(String path){ File dir = new File(path); if( !dir.exists() ){ dir.mkdir(); } return dir; } /* Checks if external storage is available for read and write */ public static boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); return Environment.MEDIA_MOUNTED.equals(state); } /* Checks if external storage is available to at least read */ public static boolean isExternalStorageReadable() { String state = Environment.getExternalStorageState(); return Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state); } } 

Además de estas dos clases, debe pasar el contexto a FileUtils, o tener algún otro medio para obtener el contexto. En el código anterior, la aplicación es una aplicación de extensión de clase para facilitar el acceso al contexto.

Recuerde también agregar Opencsv a gradle, es decir,

 compile group: 'com.opencsv', name: 'opencsv', version: '4.1' 

Luego solo llame al método de exportación de la clase exportadora Sqlite.

Primero quite esta línea para tener un documento válido con formato csv.

 printWriter.println("FIRST TABLE OF THE DATABASE"); 

En segundo lugar, asegúrese de tener datos en su tabla y compruebe si su consulta realmente devuelve algo mediante la depuración.