我正在尝试将SQLite数据导出到android中的SD卡作为目录中的CSV文件。
所以我在下面尝试过这种方法,显然它只显示了这个文字:
数据库的第一个表 日期,项目,金额,币种
在我的DBHelper.java中,我已经定义了如下函数:
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;
}
}
}
我的专栏是:
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";
如果您需要更多代码,请与我们联系。
答案 0 :(得分:28)
感谢您的建议,让我得到了这个答案:
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);
}
}
答案 1 :(得分:6)
如果有人仍然遇到这个问题,我会发布我的解决方案,这比接受的解决方案略胜一筹。您应该能够通过复制下面的两个类来导出sqlite数据库中的所有表。只需要进行其他更改即可获取应用程序上下文并导入打开的csv。
某些部分几乎是来自其他stackoverflow线程的复制粘贴,但我再也找不到了。
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<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});
}
}
<强>文件实用程序强>:
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);
}
}
除了这两个类之外,您还需要将上下文传递给FileUtils,或者使用其他方法来获取上下文。在上面的代码中,App只是扩展Application的类,以便于访问上下文。
还记得将Opencsv添加到gradle,即
compile group: 'com.opencsv', name: 'opencsv', version: '4.1'
然后只需调用Sqlite导出器类的导出方法。
答案 2 :(得分:1)
首先删除此行以获得有效的csv格式文档。
printWriter.println("FIRST TABLE OF THE DATABASE");
其次,确保您的表中有数据,并通过调试检查您的查询是否实际返回任何内容。