Allen
Allen

Reputation: 39

how to save ListView items to a csv file

Each line of the ListView contains 5 strings separated by semi-colon as follows:

str1; str2; str3; str4; str5   

The record length of the list can vary, which may sometimes reach up to 400

How can I save the list to a CSV file (in the internal storage of the device, application folder path)

Using ArrayAdapter:

private static MainActivity inst;
    ArrayList<String> inList = new ArrayList<String>();
    ListView myList;
    ArrayAdapter arrayAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myList = (ListView) findViewById(R.id.dataList);

        arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, inList);
        myList.setAdapter(arrayAdapter);

    }

Sample data in ListView:

Shop1; orange; 10; 200;2000 Shop2;orange;8;150;1200 Shop3;lemon;20;100;2000

Upvotes: 0

Views: 1908

Answers (1)

Atish Agrawal
Atish Agrawal

Reputation: 2877

I have prepared a sample activity for your reference.

public class MainActivity extends Activity {


    ArrayList<String> listDataArray;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        String line1 = "Shop1; orange; 10; 200;2000";
        String line2 = "Shop2;orange;8;150;1200";
        String line3 = "Shop3;lemon;20;100;2000";

        listDataArray = new ArrayList<>();

        listDataArray.add(line1);
        listDataArray.add(line2);
        listDataArray.add(line3);


        ArrayAdapter arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listDataArray);
        ((ListView) findViewById(R.id.listviewData)).setAdapter(arrayAdapter);


    }


    public void processCSV(View view) {

        try {

            boolean writePermissionStatus = checkStoragePermission(false);
            //Check for permission
            if (!writePermissionStatus) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                return;
            } else {
                boolean writePermissionStatusAgain = checkStoragePermission(true);
                if (!writePermissionStatusAgain) {
                    Toast.makeText(this, "Permission not granted", Toast.LENGTH_LONG).show();
                    return;
                } else {
                    //Permission Granted. Export
                    exportDataToCSV();

                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String toCSV(String[] array) {
        String result = "";
        if (array.length > 0) {
            StringBuilder sb = new StringBuilder();
            for (String s : array) {
                sb.append(s.trim()).append(",");
            }
            result = sb.deleteCharAt(sb.length() - 1).toString();
        }
        return result;
    }


    private void exportDataToCSV() throws IOException {


        String csvData = "";

        for (int i = 0; i < listDataArray.size(); i++) {

            String currentLIne = listDataArray.get(i);
            String[] cells = currentLIne.split(";");

            csvData += toCSV(cells) + "\n";

        }


        File directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
        String uniqueFileName = "FileName.csv";
        File file = new File(directory, uniqueFileName);
        FileWriter fileWriter = new FileWriter(file);
        fileWriter.write(csvData);
        fileWriter.flush();
        fileWriter.close();
        Toast.makeText(MainActivity.this, "File Exported Successfully", Toast.LENGTH_SHORT).show();

    }


    private boolean checkStoragePermission(boolean showNotification) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                if (showNotification) showNotificationAlertToAllowPermission();
                return false;
            }
        } else {
            return true;
        }
    }


    private void showNotificationAlertToAllowPermission() {
        new AlertDialog.Builder(this).setMessage("Please allow Storage Read/Write permission for this app to function properly.").setPositiveButton("Open Settings", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivity(intent);
            }
        }).setNegativeButton("Cancel", null).show();

    }

}

Explanation

  1. I have created 3 static String with the input as you provided.
  2. I created an ArrayList adding all these 3 sample data. We would be assuming this ArrayList to be the data.
  3. Created an Adapter same as you were trying to implement, and then added it to the ListView for displaying.
  4. Created a Button Export CSV to export CSV to the external directory Downloads Folder.
  5. Other helpful methods for permission checks and converters.

When the user clicks, Export CSV, the following process starts:

  1. The first task is to check if the user has given permissions to export the CSV or not. If No, request for permission, otherwise, continue to exportDataToCSV() method.
  2. In this function, Loop though all the rows (lines) in the ArrayList which you created to populate the listview (by setting in the adapter), and get the currentLine.
  3. Split the contents using ; as a separator and create a local String Array.
  4. Pass this array to toCSV method, which joins the data with , as this will be used to create CSV (Comma Separated Values). Append a blank line \n at the end of each line to create rows.
  5. Finally, once you have all the data in the String csvData, Write the output to a file.

Obviously, there could be more efficient ways of doing this, but I have separated each function as far as possible, to make it easy to understand.

The other way to generate CSV from the currentLine, could be to replace ; with , directly. You should try that by yourself.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listviewData"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:onClick="processCSV"
        android:text="Export CSV" />

</LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.myapplication">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Upvotes: 1

Related Questions