สำหรับใครที่ใช้ฐานข้อมูลเป็นภาษาไทย ให้เปลี่ยน Encoding จาก ANSI เป็น UTF-8 เพื่อแก้ปัญหาแสดงภาษาไทยเพี้ยนด้วย [Android Code] แก้ปัญหาภาษาไทยใน CSV แสดงผลเพี้ยน
จากคราวก่อนที่เข้าของบล็อกพล่ามเรื่องฐานข้อมูลแล้ว ทีนี้การสร้างฐานข้อมูลขึ้นมาก็ต้องมีข้อมูลที่จะเอามาเก็บ ซึ่งก็แล้วแต่ว่าข้อมูลนั้นๆจะเอามาจากไหน จะให้ผู้ใช้แอพใส่ข้อมูลแล้วเก็บลงฐานข้อมูลก็ได้ หรือจะพิมใส่เตรียมไว้ก็ได้ (แบบตัวอย่างก่อนหน้า) หรือนำเข้าจากไฟล์ฐานข้อมูลต่างๆ
ซึ่งเจ้าของบล็อกก็จะขอพูดถึงการนำเข้าข้อมูลจากไฟล์ CSV มาเก็บไว้ในฐานข้อมูลของแอพฯกัน ก่อนอื่นเลยเราก็ต้องมีไฟล์ CSV ที่จะเอามานำเข้าก่อน เจ้าของบล็อกก็เลยสร้างขึ้นมาเพื่อใช้เป็นตัวอย่าง โดยมีข้อมูลดังนี้
package app.akexorcist.databaseimportcsv;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import android.os.Bundle;
import android.util.Log;
import android.app.Activity;
public class Main extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(getAssets().open(
"customerdata.csv")));
String readLine = null;
try {
while ((readLine = br.readLine()) != null) {
Log.i("Data Input", readLine);
}
} catch (IOException e) { }
} catch (IOException e) { }
}
}
เริ่มจากที่คลาส BufferReader ก่อนเลยละกัน โดยคลาสที่ว่านี้เป็นคลาสสำหรับอ่านข้อมูลจากไฟล์ ซึ่งเจ้าของบล็อกกำหนดให้อ่านไฟล์ customdata.csv ที่อยู่ในส่วนของ Assets โดยใช้คำสั่ง
getAssets().open("customerdata.csv")
มาเก็บไว้ใน InputStreamReader ก่อน แล้วเอามาเก็บใน BufferReader ต่อเลย แต่จะเห็นว่าเจ้าของบล็อกใช้คำสั่งแค่บรรทัดเดียวสร้าง InputStreamReader แล้วส่งค่าให้ BufferRead เลย ต่อมาก็ทำการสร้างตัวแปร String ขึ้นมาชื่อ readLine เอาไว้เก็บ String ของแต่ละแถว มาแสดงใน Log สำหรับการอ่าน String ในแต่ละแถว ก็จะใช้คำสั่ง
readLine = br.readLine()
เมื่อใช้คำสั่งนี้อีกครั้งจะเป็นการอ่านค่าในแถวต่อไปเรื่อยๆ โดยเช็คว่าค่าที่ได้เป็น null หรือป่าว ถ้าใช่ก็คืออ่านครบแล้ว จากนั้นก็จะแสดงข้อมูลผ่านหน้าต่าง LogCat ด้วยคำสั่ง
Log.i("Data Input", readLine);
และเนื่องจากใช้ while วนรอบไปเรื่อยๆ ก็จะแสดงข้อมูล จากตัวแปร readLine ทุกๆครั้งที่มีการอ่านค่าบรรทัดใหม่จนครบ เมื่อลองทดสอบการทำงาน ก็จะเห็นว่า LogCat มีข้อความแสดงขึ้นมาเมื่อเปิดแอพ
จะเห็นว่าข้อมูลที่ออกมาจะเป็นดังนี้
Name,Job,Age,Gender
Akito,Student,20,Male
Madeil,Student,19,Female
Henry,Engineer,32,Male
Densell,Magician,8,Male Elf
ข้อมูลในแต่ละคอลัมน์จะถูกคั่นด้วยเครื่องหมายลูกน้ำ
String[] str = readLine.split(",");
ก็จะทำให้ข้อมูลแบ่งออกเป็นสี่คอลัมน์ด้วยกัน ซึ่งในแต่ละช่องก็จะมีข้อมูลดังนี้ (สมมติว่าแถวแรกสุด)
strRow[0] : Name
strRow[1] : Job
strRow[2] : Age
strRow[3] : Gender
และเมื่อแบ่งข้อมูลครบทุกๆแถวแล้วก็จะได้ประมาณนี้
Database.java
package app.akexorcist.databaseimportcsv;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
class Database extends SQLiteOpenHelper {
private static final String DB_NAME = "My Business Data";
private static final int DB_VERSION = 1;
public static final String TABLE_NAME = "Customer";
public static final String COL_NAME = "name";
public static final String COL_JOB = "job";
public static final String COL_AGE = "age";
public static final String COL_GENDER = "gender";
Context context;
public Database(Context ctx) {
super(ctx, DB_NAME, null, DB_VERSION);
context = ctx;
}
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME
+ " (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COL_NAME + " TEXT, " + COL_JOB + " TEXT, "
+ COL_AGE + " INTEGER, " + COL_GENDER + " TEXT);");
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(context.getAssets().open(
"customerdata.csv")));
String readLine = null;
readLine = br.readLine();
try {
while ((readLine = br.readLine()) != null) {
String[] str = readLine.split(",");
db.execSQL("INSERT INTO " + TABLE_NAME
+ " (" + COL_NAME + ", " + COL_JOB
+ ", " + COL_AGE + ", " + COL_GENDER
+ ") VALUES ('" + str[0]
+ "', '" + str[1] + "', " + str[2]
+ ", '" + str[3] + "');");
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void onUpgrade(SQLiteDatabase db, int oldVersion
, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
คอลัมน์ของฐานข้อมูลเจ้าของบล็อกจะกำหนดชื่อเป็น name, job, age, gender ตามที่ต้องการไว้ แล้วใช้คำสั่ง
readLine = br.readLine();
ครั้งหนึ่งก่อน เพื่อข้ามแถวแรกไปเพราะเป็นแค่ชื่อตาราง จากนั้นก็จะทำการทยอยแบ่งข้อมูลออกเป็นส่วนๆแล้วเก็บลงในฐานข้อมูล จนครบ
ทีนี้มาที่หน้า Main.java ของเจ้าของบล็อก ก็จะกำหนดให้แสดงฐานข้อมูลที่มีอยู่ผ่าน List View
Main.java
package app.akexorcist.databaseimportcsv;
import java.util.ArrayList;
import android.os.Bundle;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class Main extends Activity {
SQLiteDatabase mDb;
Database mHelper;
Cursor mCursor;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
ListView listView1 = (ListView)findViewById(R.id.listView1);
mHelper = new Database(this);
mDb = mHelper.getWritableDatabase();
mHelper.onUpgrade(mDb, 1, 1);
mCursor = mDb.rawQuery("SELECT " + Database.COL_NAME + ", "
+ Database.COL_JOB + ", " + Database.COL_AGE + ", "
+ Database.COL_GENDER + " FROM " + Database.TABLE_NAME, null);
ArrayList<String> dirArray = new ArrayList<String>();
mCursor.moveToFirst();
while ( !mCursor.isAfterLast() ){
dirArray.add("Name : " + mCursor.getString
(mCursor.getColumnIndex(Database.COL_NAME)) + "\n"
+ "Job : " + mCursor.getString(mCursor.getColumnIndex
(Database.COL_JOB)) + "\n"
+ "Age : " + mCursor.getString(mCursor.getColumnIndex
(Database.COL_AGE)) + "\n"
+ "Gender : " + mCursor.getString(mCursor.getColumnIndex
(Database.COL_GENDER)));
mCursor.moveToNext();
}
ArrayAdapter<String> adapterDir =
new ArrayAdapter<String>(getApplicationContext()
, android.R.layout.simple_list_item_1, dirArray);
listView1.setAdapter(adapterDir);
}
public void onPause() {
super.onPause();
mHelper.close();
mDb.close();
}
}
และสำหรับ main.xml เจ้าของบล็อกขอใช้เหมือนตัวอย่างที่แล้วละกัน
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#666666" >
<TextView
android:id="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Customer"
android:textColor="#222222"
android:textSize="40dp"
android:gravity="center"
android:layout_marginTop="20dp" />
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:cacheColorHint="#00000000" />
</LinearLayout>
ทีนี้ก็ลองทดสอบแอพฯดู ก็จะเห็นว่าไฟล์ CSV ได้ถูกเก็บลงบนฐานข้อมูลแล้วนำมาแสดงบน List View แล้ว
สำหรับผู้ที่หลงเข้ามาอ่านที่อยากจะเอาไฟล์ตัวอย่างไปลองก็ดาวน์โหลดจากตรงนี้ได้เลย Database Import CSV [Google Drive]