将 .csv 文件导入 Android 中的 Sqlite

Posted

技术标签:

【中文标题】将 .csv 文件导入 Android 中的 Sqlite【英文标题】:Import .csv file to Sqlite in Android 【发布时间】:2013-05-16 08:13:05 【问题描述】:

我有一个 .csv 文件,我想将此文件导入我的 android 数据库中。

例如,.csv 文件:

| id | name  | dt1 | dt2 | dt3 | 
| 1  | Paul  | 21  | 98  | 91  |
| 2  | John  | 22  | 44  | 11  |
| 3  | George| 21  | 31  | 22  |
| 4  | Ringo | 20  | 10  | 15  | 

对于这样的事情:

Cursor cursor = getWritableDatabase().
rawQuery("Insert into table1(_id, name, dt1, dt2, dt3)
values ( 1, Paul, 21, 98, 91)
values ( 2, John, 22, 44, 11)
values ( 3, George, 21,31,22)
values ( 4, Ringo, 20, 10,15);");

那么请问,我该怎么做呢?

【问题讨论】:

【参考方案1】:

试试下面的代码,

FileReader file = new FileReader(fileName);
BufferedReader buffer = new BufferedReader(file);
String line = "";
String tableName ="TABLE_NAME";
String columns = "_id, name, dt1, dt2, dt3";
String str1 = "INSERT INTO " + tableName + " (" + columns + ") values(";
String str2 = ");";

db.beginTransaction();
while ((line = buffer.readLine()) != null) 
    StringBuilder sb = new StringBuilder(str1);
    String[] str = line.split(",");
    sb.append("'" + str[0] + "',");
    sb.append(str[1] + "',");
    sb.append(str[2] + "',");
    sb.append(str[3] + "'");
    sb.append(str[4] + "'");
    sb.append(str2);
    db.execSQL(sb.toString());

db.setTransactionSuccessful();
db.endTransaction();

【讨论】:

实际上,如果 csv 下载到文件夹或资产文件夹中,我不明白我应该在FileReader file = new FileReader(fileName); 写什么。我尝试使用此代码AssetFileDescriptor descriptor = getAssets().openFd("myfile.csv"); FileReader reader = new FileReader(descriptor.getFileDescriptor());,但它给出了错误 Caused by: java.io.FileNotFoundException: This file can't be open as a file descriptor;它可能被压缩了 @mehmet 你可以这样做。 InputStream is = getAssets().open("myfile.csv"); 然后BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); 有了这个,我不断收到FileNotFoundException 这是因为它在模拟器上查看Android文件系统吗? @Saher,FileNotFoundException 通常在找不到您定义的路径时出现。尝试在“日志”中打印完整路径并交叉检查您指定的文件是否被您的代码占用。 这里的db是什么?【参考方案2】:

我建议使用 ContentValues 来插入记录。它更容易,会转义引号,并且不那么冗长。

像这样,(它也会跳过坏行):

 ...
 BufferedReader buffer = new BufferedReader(new InputStreamReader(inStream));
 String line = "";
 db.beginTransaction();
        try 
            while ((line = buffer.readLine()) != null) 
                String[] colums = line.split(",");
                if (colums.length != 4) 
                    Log.d("CSVParser", "Skipping Bad CSV Row");
                    continue;
                
                ContentValues cv = new ContentValues(3);
                cv.put(dbCol0, colums[0].trim());
                cv.put(dbCol1, colums[1].trim());
                cv.put(dbCol2, colums[2].trim());
                cv.put(dbCol3, colums[3].trim());
                cv.put(dbCol4, colums[4].trim());
                db.insert(TABLE, null, cv);
            
         catch (IOException e) 
            e.printStackTrace();
        
   db.setTransactionSuccessful();
   db.endTransaction();

dbCol0 等是数据库的列名,例如_id, name, dt1, dt2, dt3.

db 是您从中获取的数据库 public SQLiteDatabase getReadableDatabase () 在 SQLiteOpenHelper 中

如何读取 CSV 文件

file.csv 复制到 assets 文件夹中,然后像这样读取它:

String mCSVfile = "file.csv";
AssetManager manager = context.getAssets();
InputStream inStream = null;
try 
     inStream = manager.open(mCSVfile);
     catch (IOException e) 
     e.printStackTrace();
    

 BufferedReader buffer = new BufferedReader(new InputStreamReader(inStream));
...

【讨论】:

这种情况下.csv文件应该放在哪里? 资产文件夹(如写) 这里的db和dbCol0是什么? @Kala J 在回答中添加了信息 由于某种原因我得到了,(1)没有这样的表,错误。【参考方案3】:

我添加了一些使用这些类的类,您可以轻松导入和导出文件或数据库

对于这些操作,您必须将这两个 jar 文件导入到您的项目中(1) opencsv-1.7.jar http://www.java2s.com/Code/Jar/o/Downloadopencsv17jar.htm(2) poi-3.8-20120326.jarhttp://code.google.com/p/mipgsmca12-108-126--online-library/downloads/detail?name=poi-3.8-20120326.jar&can=2&q= 而不是导入所有这四个类,并根据需要使用...ExportFileModule `

public class ExportDatabaseToCSV extends AsyncTask<Void, Boolean, Boolean>

Context context;
ProgressDialog dialog;
public ExportDatabaseToCSV(Context context)

    this.context=context;   


@Override
protected void onPreExecute() 
    dialog=new ProgressDialog(context);
    dialog.setTitle("Exporting SecureIt Data to CSV file");
    dialog.setMessage("Please wait...");
    dialog.setCancelable(false);
    dialog.setIcon(android.R.drawable.ic_dialog_info);
    dialog.show();


@Override
protected Boolean doInBackground(Void... params) 
    CredentialDb db = new CredentialDb(context);//here CredentialDb is my database. you can create your db object.
       File exportDir = new File(Environment.getExternalStorageDirectory(), "");        

       if (!exportDir.exists()) 
          
              exportDir.mkdirs();
          

      File file = new File(exportDir, "SecureItExportedFile.csv");

      try 
      
          file.createNewFile();                
          CSVWriter csvWrite = new CSVWriter(new FileWriter(file));
          SQLiteDatabase sql_db = db.getReadableDatabase();//returning sql
          Cursor curCSV = sql_db.rawQuery("SELECT * FROM "+CredentialDb.TABLE_NAME,null);
          csvWrite.writeNext(curCSV.getColumnNames());

          while(curCSV.moveToNext())
              
                 //Which column you want to export you can add over here...
                  String arrStr[] =curCSV.getString(0),curCSV.getString(1), curCSV.getString(2),curCSV.getString(3),curCSV.getString(4),curCSV.getString(5);
                  csvWrite.writeNext(arrStr);
              

          csvWrite.close();
          curCSV.close();
          return true;
      
      catch(Exception sqlEx)
      
          Log.e("Error:", sqlEx.getMessage(), sqlEx);
      
      return false;
   

@Override
protected void onPostExecute(Boolean result) 
    if (dialog.isShowing())
    
        dialog.dismiss();
    

    if(result)
        Toast.makeText(context, "SqLite Data has been Exported!", Toast.LENGTH_LONG).show();
    else
        Toast.makeText(context, "SqLite Data has not Exported", Toast.LENGTH_LONG).show();  


导入模块

import java.io.File;

import android.app.Activity;
import android.content.Context;
import android.os.Environment;

public class MyCSVFileReader 

public static void openDialogToReadCSV(final Activity activity,final Context context)

    File mPath = new File(Environment.getExternalStorageDirectory() + "//DIR//");
    FileDialog fileDialog = new FileDialog(activity, mPath);
    fileDialog.setFileEndsWith(".txt");
    fileDialog.addFileListener(new FileDialog.FileSelectedListener() 

        @Override
        public void fileSelected(File file) 
            new ImportCVSToSQLiteDataBase(context,activity,file).execute(); //execute asyncTask to import data into database from selected file.            
        
    );
    fileDialog.showDialog();



import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Environment;
import android.util.Log;

import com.export.importmodule.ListenerList.FireHandler;

public class FileDialog 
    private static final String PARENT_DIR = "..";
    private final String TAG = getClass().getName();
    private String[] fileList;
    private File currentPath;

public interface FileSelectedListener 
    void fileSelected(File file);

public interface DirectorySelectedListener 
    void directorySelected(File directory);

private ListenerList<FileSelectedListener> fileListenerList = new ListenerList<FileDialog.FileSelectedListener>();
private ListenerList<DirectorySelectedListener> dirListenerList = new ListenerList<FileDialog.DirectorySelectedListener>();
private final Activity activity;
private boolean selectDirectoryOption;
private String fileEndsWith;    

/**
 * @param activity 
 * @param initialPath
 */
public FileDialog(Activity activity, File path) 
    this.activity = activity;
    if (!path.exists()) path = Environment.getExternalStorageDirectory();
    loadFileList(path);


/**
 * @return file dialog
 */
public Dialog createFileDialog() 
    Dialog dialog = null;
    AlertDialog.Builder builder = new AlertDialog.Builder(activity);

    builder.setTitle(currentPath.getPath());
    if (selectDirectoryOption) 
        builder.setPositiveButton("Select directory", new OnClickListener() 
            public void onClick(DialogInterface dialog, int which) 
                Log.d(TAG, currentPath.getPath());
                fireDirectorySelectedEvent(currentPath);
            
        );
    

    builder.setItems(fileList, new DialogInterface.OnClickListener() 
        public void onClick(DialogInterface dialog, int which) 
            String fileChosen = fileList[which];
            File chosenFile = getChosenFile(fileChosen);
            if (chosenFile.isDirectory()) 
                loadFileList(chosenFile);
                dialog.cancel();
                dialog.dismiss();
                showDialog();
             else fireFileSelectedEvent(chosenFile);
        
    );

    dialog = builder.show();
    return dialog;



public void addFileListener(FileSelectedListener listener) 
    fileListenerList.add(listener);


public void removeFileListener(FileSelectedListener listener) 
    fileListenerList.remove(listener);


public void setSelectDirectoryOption(boolean selectDirectoryOption) 
    this.selectDirectoryOption = selectDirectoryOption;


public void addDirectoryListener(DirectorySelectedListener listener) 
    dirListenerList.add(listener);


public void removeDirectoryListener(DirectorySelectedListener listener) 
    dirListenerList.remove(listener);


/**
 * Show file dialog
 */
public void showDialog() 
    createFileDialog().show();


private void fireFileSelectedEvent(final File file) 
    fileListenerList.fireEvent(new FireHandler<FileDialog.FileSelectedListener>() 
        public void fireEvent(FileSelectedListener listener) 
            listener.fileSelected(file);
        
    );


private void fireDirectorySelectedEvent(final File directory) 
    dirListenerList.fireEvent(new FireHandler<FileDialog.DirectorySelectedListener>() 
        public void fireEvent(DirectorySelectedListener listener) 
            listener.directorySelected(directory);
        
    );


private void loadFileList(File path) 
    this.currentPath = path;
    List<String> r = new ArrayList<String>();
    if (path.exists()) 
        if (path.getParentFile() != null) r.add(PARENT_DIR);
        FilenameFilter filter = new FilenameFilter() 
            public boolean accept(File dir, String filename) 
                File sel = new File(dir, filename);
                if (!sel.canRead()) return false;
                if (selectDirectoryOption) return sel.isDirectory();
                else 
                    boolean endsWith = fileEndsWith != null ? filename.toLowerCase().endsWith(fileEndsWith) : true;
                    return endsWith || sel.isDirectory();
                
            
        ;
        String[] fileList1 = path.list(filter);
        for (String file : fileList1) 
            r.add(file);
        
    
    fileList = (String[]) r.toArray(new String[]);


private File getChosenFile(String fileChosen) 
    if (fileChosen.equals(PARENT_DIR)) return currentPath.getParentFile();
    else return new File(currentPath, fileChosen);


   
//--------------------------------------------------------------
    public void setFileEndsWith(String fileEndsWith) 
        this.fileEndsWith = fileEndsWith != null ? fileEndsWith.toLowerCase() : fileEndsWith;
        
     

class ListenerList<L> 
private List<L> listenerList = new ArrayList<L>();

public interface FireHandler<L> 
    void fireEvent(L listener);


public void add(L listener) 
    listenerList.add(listener);


public void fireEvent(FireHandler<L> fireHandler) 
    List<L> copy = new ArrayList<L>(listenerList);
    for (L l : copy) 
        fireHandler.fireEvent(l);
    


public void remove(L listener) 
    listenerList.remove(listener);


public List<L> getListenerList() 
    return listenerList;


import java.io.File;
import java.io.FileReader;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import au.com.bytecode.opencsv.CSVReader;

public class ImportCVSToSQLiteDataBase extends AsyncTask<String, String, String> 

    Activity activity;
    Context context;
    File file=null;
    private ProgressDialog dialog;

    public ImportCVSToSQLiteDataBase(Context context, Activity activity,File file) 
        this.context=context;
        this.activity=activity;
        this.file=file;
    

    @Override
    protected void onPreExecute()
    
        dialog=new ProgressDialog(context);
        dialog.setTitle("Importing Data into SecureIt DataBase");
        dialog.setMessage("Please wait...");
        dialog.setCancelable(false);
        dialog.setIcon(android.R.drawable.ic_dialog_info);
        dialog.show();
    

@Override
protected String doInBackground(String... params) 

            String data="";
            Log.d(getClass().getName(), file.toString());

           try
                 CSVReader reader = new CSVReader(new FileReader(file));
                   String [] nextLine;

                  //here I am just displaying the CSV file contents, and you can store your file content into db from while loop...

                    while ((nextLine = reader.readNext()) != null) 

                        // nextLine[] is an array of values from the line

                        String accId=nextLine[0];
                        String acc_name=nextLine[1];

                        data=data+"AccId:"+accId  +"  Account_name:"+acc_name+"\n";

                      
                   return data;

             catch (Exception e) 
                Log.e("Error", "Error for importing file");
            
        return data="";

  

protected void onPostExecute(String data)
  

    if (dialog.isShowing())
    
        dialog.dismiss();
    

    if (data.length()!=0)
    
        Toast.makeText(context, "File is built Successfully!"+"\n"+data, Toast.LENGTH_LONG).show();
    else
            Toast.makeText(context, "File fail to build", Toast.LENGTH_SHORT).show();
         
   



使用步骤...(1) 对于导出 SqLiteDb:新的 ExportDatabaseToCSV(YourActivityClass.this).execute(); (2) 从您选择的文件中导入 SqLiteDb:MyCSVFileReader.openDialogToReadCSV(this, YourActivityClass.this);

(3)并且不要忘记在AndroidManifest.xml中添加这些权限

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

【讨论】:

看起来是个不错的解决方案,只是这些 .jar 文件让我使用起来有点不舒服。 :// 这里 :) github.com/rogerta/secrets-for-android/tree/master/app/src/main/…

以上是关于将 .csv 文件导入 Android 中的 Sqlite的主要内容,如果未能解决你的问题,请参考以下文章

如何将手机中的csv文件的内容导入到SQLite数据库中

将用户 .csv 文件中的数据导入表中

如何将带有 YYYYMMDD 列的 CSV 文件导入 ClickHouse 中的 DATE 列

R 中的 fread 将一个大的 .csv 文件导入为一行的数据框

将大型 .csv 文件导入 Excel,

将CSV文件中的数据导入到SQL Server 数据库中