2015-07-12 15 views
10

Tôi đang cố gắng xuất dữ liệu SQLite sang thẻ SD trong android dưới dạng tệp CSV trên một thư mục.Xuất cơ sở dữ liệu SQLite sang tệp csv trong android

Vì vậy, tôi đã thử phương pháp dưới đây và dường như nó chỉ hiển thị văn bản này in ra:

BẢNG ĐẦU CỦA CƠ SỞ DỮ LIỆU
NGÀY, ITEM, AMOUNT, TỆ

Trong DBHelper.java của tôi tôi đã xác định các chức năng như sau:

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; 
     } 
    } 
} 

Và cột của tôi là:

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"; 

Hãy cho tôi biết nếu bạn cần thêm mã.

+0

bạn muốn gì? bạn nhận được bất kỳ lỗi nào. – RajSharma

+1

'// Viết tên của bảng và tên của các cột (giá trị được phân cách bằng dấu phẩy) trong tệp .csv.' Sau đó, nó không còn là tệp CSV hợp lệ nữa, nếu bạn thêm tên bảng. Dòng đầu tiên trong tệp CSV hợp lệ hoặc là hàng tiêu đề có tên cột hoặc chỉ là hàng dữ liệu đầu tiên. –

+0

Đối với những gì liên quan đến vấn đề của bạn ... có vẻ như không có dữ liệu trong bảng. –

Trả lời

21

Cám ơn lời đề nghị chàng trai của bạn mà dẫn tôi đến câu trả lời này:

private void exportDB() { 
 

 
     File dbFile=getDatabasePath("MyDBName.db"); 
 
     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); 
 
     }

+0

Không rõ ràng ở đâu để lấy 'getDatabasePath',' DBHelper', 'CSVWriter' và các phần khác của mã này. – zygimantus

+0

'getDatabasePath()' phương thức tìm đường dẫn của vị trí cơ sở dữ liệu, 'DBHelper' là lớp xử lý sqlite của tôi mở rộng' sqliteOpenHelper', 'CSVWriter' là hàm CSV. Mã hoạt động trực tiếp mà không cần phải hối hả. –

+0

Một điều đáng tiếc là bạn không chia sẻ những lớp học ở đây. Chúng có thể hữu ích cho người khác. Bạn có thể tìm thấy – leoneboaventura

1

Trước hết, hãy xóa dòng này để có tài liệu có định dạng csv hợp lệ.

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

Thứ hai, hãy đảm bảo bạn có dữ liệu trong bảng và kiểm tra xem truy vấn của bạn có thực sự trả về bất kỳ điều gì không bằng cách gỡ lỗi.

1

Trong trường hợp ai đó vẫn còn tình cờ gặp câu hỏi này, tôi sẽ gửi giải pháp của tôi, đó là hơi tổng quát hơn cái được chấp nhận. Bạn sẽ có thể xuất tất cả các bảng trong cơ sở dữ liệu sqlite gần như bằng cách sao chép hai lớp bên dưới. Chỉ những thay đổi khác cần phải có liên quan đến việc nhận bối cảnh ứng dụng và nhập csv mở.

Một số phần được dán khá nhiều từ các luồng ngăn xếp khác, nhưng tôi không thể tìm thấy chúng nữa.

Sqlite xuất khẩu:

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<String> 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<String> getTablesOnDataBase(SQLiteDatabase db){ 
     Cursor c = null; 
     List<String> 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<String> 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); 
    } 
} 

Ngoài hai loại cổ phiếu này, bạn có cần phải vượt qua bối cảnh vào FileUtils, hoặc có một số phương tiện khác nhận bối cảnh. Trong mã trên App chỉ là lớp mở rộng ứng dụng để dễ dàng truy cập vào ngữ cảnh.

Cũng nên nhớ để thêm Opencsv để gradle, ví dụ:

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

Sau đó chỉ cần gọi phương thức xuất khẩu của lớp xuất khẩu Sqlite.

+0

Cách gọi phương thức này từ MainActivity ? – user2872856

+0

Bạn có thể gọi nó bằng 'SqliteExporter.export (db)' trong đó db là đối tượng SQLiteDatabase, bạn có thể lấy ví dụ từ sqliteOpenHelper với getReadableDatabase() – Pete

+0

Có thể bạn muốn gọi phương thức export từ một luồng nền, vì có thể mất một lúc để xuất cơ sở dữ liệu. Đối với điều này, bạn có thể muốn tạo một intentService hoặc một cái gì đó khác mà không chặn luồng ui. – Pete

Các vấn đề liên quan