1

I am creating a .csv file from my Android application and storing the data in .csv format. However, when the length of a particular cell's value exceeds a certain number of characters, it leaves that cell and moves to a completely new row towards the first column. How can I display within the same cell?

Here is the code I am using to create and save data in .csv format from my android application.


public class ReportListingActivity extends AppCompatActivity {


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK)
            return;

        switch (requestCode) {
            case CREATE_FILE:
                if (data != null) {
                    Uri uri = data.getData();
                    if (uri != null) {
                        new ExportCSV(this).execute(uri);
                    }
                }
                break;
        }
    }

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



    private void createFile() {
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("text/csv");
        intent.putExtra(Intent.EXTRA_TITLE, "stored_data.csv");


        startActivityForResult(intent, CREATE_FILE);
    }

    private class ExportCSV extends AsyncTask<Uri, Void, Boolean> {
        private final WeakReference<Context> context;

        ExportCSV(Context c) {
            context = new WeakReference<>(c);
        }

        @Override
        protected Boolean doInBackground(Uri... uris) {
            Uri uri = uris[0];
            Context c = context.get();


            if( c == null ) {
                return false;
            }

//updated code
StringBuilder data = new StringBuilder();
data.append("Flight Number, Departure Date, Comments");

String first_comment = "hello this is an example of the comments that I am talking about in this case. If I keep typing it will move to the next row which i do not want at all. lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum";

String second_comment = "It is long and it moves" + "\n" + "to the first column and subsequent rows";

pre_comments1 = "1) " + first_comment  + "\n";
pre_comments2 = "2) " + second_comment + "\n";

pre_comments_consolidated = pre_comments1 + pre_comments2;

data.append("\n" + flightNumber + "," + departureDate + ","+ pre_comments_consolidated);

//until here
            try {
                OutputStream os = c.getContentResolver().openOutputStream(uri);
                if(os!=null) {
                    os.write(data.toString().getBytes());
   
                    os.close();
                }
            }
            catch(Exception e) {
                e.printStackTrace();
            }
            return true;
        }
    }

}

Below is a screenshot of the output I am getting when I open the csv file in Excel

The text from Column3 moves to Column1 and subsequent rows when the text is too long or when it has new line characters (\n). How can I fix it and just display it within the same cell i.e. Column3?

excel output

The second image shows the new output when I use double quotes on my variables to append data to my csv file.

New output when I use double quotes on my variables to append data to my csv file

Ian Bell
  • 533
  • 5
  • 18
  • [This page](https://www.excelchamp.net/adding-line-breaks-in-a-csv-file/) says you need to quote the entries containing line breaks. As in `data.append("\"Hello\nworld\"")`. – Eugen Pechanec Feb 22 '21 at 19:51
  • What if I want to pass in a variable? – Ian Bell Feb 22 '21 at 19:58
  • @EugenPechanec Moreover, even when the String doesn't contain a line break, it goes to the first column and subsequent rows. – Ian Bell Feb 22 '21 at 20:10
  • `What if I want to pass in a variable?` You can join strings with other things using `+`. Verify the output in something simple, like Notepad. Excel isn't reliable unless you use the *Data > Import from CSV* function. The image in your question doesn't match the code, so it's impossible for me to tell what's wrong. – Eugen Pechanec Feb 22 '21 at 20:44
  • @EugenPechanec I have updated the code and image and now they are same, the code matches the output, so could you please help with there? Thanks! :) – Ian Bell Feb 22 '21 at 20:59
  • @EugenPechanec where do I exactly place the quotes that you were referring to in the first comment? – Ian Bell Feb 22 '21 at 21:08
  • If you want a line break to be part of the value, you need to quote the value _inside the string_ - wrap _the value_ in `"`. Don't get it confused with quotes you need to produce strings in Java. Example: `"\"This\nwill\nbe\na\nmultiline\nvalue\""` Note the escaped quotes (`\"`) within the outer string quotes. – Eugen Pechanec Feb 22 '21 at 21:09
  • You may also want to simplify you strings for reading, example `"1) " + "hello" + "\n";` is actually just `"1) hello\n"`. – Eugen Pechanec Feb 22 '21 at 21:11
  • @EugenPechanec I have updated the code above, and that is exactly how it is in my application. Basically, I have strings stored as variables. Where exactly do I place the quotes so that I can get line break within same call in css file? – Ian Bell Feb 22 '21 at 21:18
  • Wrap the values in quotes. You CSV looks like this: `String csv = "some value, other value\nwith line break";` It needs to look like this: `String csv = "\"some value\",\"other value\nwith line break\"";`. [This may help you.](https://stackoverflow.com/questions/3559063/how-to-enter-quotes-in-a-java-string) – Eugen Pechanec Feb 22 '21 at 21:24
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/229058/discussion-between-ian-bell-and-eugen-pechanec). – Ian Bell Feb 22 '21 at 21:28
  • @EugenPechanec For my application, the first_comment string and the second_comment string, I am getting it from a database, hence I am not declaring the string anywhere in the activity. The long string in the first_comment and second_comment string variable comes from my Rooms database directly and hence I am not hardcoding the strings. So where do I place the double quotes in the code? – Ian Bell Feb 22 '21 at 21:32
  • `So where do I place the double quotes in the code?` Around the CSV values. It's not important if the value is hardcoded or from database. You know where you put the CSV values together, so add the quotes at the same time. – Eugen Pechanec Feb 22 '21 at 22:24
  • When I wrap the values in quotes to the place where I am putting my csv values together, it just prints the variable name as a string. here is the code ` data.append("\n" + "\"flightNumber\"" + "," + "\"departureDate\"" + ","+ "\"pre_comments_consolidated\""); `. In the excel file, it prints flightNumber, departureDate and pre_comments_consolidated as values. I am adding the screenshot of the output in the question above. – Ian Bell Feb 23 '21 at 07:51
  • @EugenPechanec how can I fix this? – Ian Bell Feb 23 '21 at 08:03
  • Do you understand the difference between `"\n" + "\"" + flightnumber + "\""` and `"\n" + "\"" + "flightnumber" + "\""`? – Eugen Pechanec Feb 23 '21 at 08:14
  • 1
    I see, its more clear now, thanks a lot! The first one uses the value of the variable flightnumber and the second one prints flightnumber itself as a string. – Ian Bell Feb 23 '21 at 08:42
  • Thanks a ton @EugenPechanec , your help solved the issue I was facing! :) – Ian Bell Feb 23 '21 at 08:43

1 Answers1

2

You need to understand the difference between

"\n" + "\"" +  flightnumber  + "\""

and

"\n" + "\"" + "flightnumber" + "\""
"\n" + "\"flightnumber\""
"\n\"flightnumber\""

For better readability, and since StringBuilder is already used to concatenate strings, here's everything on a separate line:

data.append("Flight Number");
data.append(',');
data.append("Departure Date");
data.append(',');
data.append("Comments");
data.append('\n');
// ...
data.append(flightNumber);
data.append(',');
data.append(departureDate);
data.append(',');
data.append('"' + pre_comments_consolidated + '"');

Notes:

  • Put single characters in single quotes : '\n', 'a', 'b', 'c'
  • You don't have to escape double quotes inside single quotes and vice versa: "'", '"'
  • You can concatenate characters and strings: "example" + '\n'
  • You're joining literal double quotes with variable pre_comments_consolidated.

This will not work properly if the CSV value contains quotes. You'll need to CSV-escape them. You should consider putting all that logic in a separate function.

private String escapeCsv(String in) {
    // Double double quotes that are already part of the value.
    String out = in.replace("\"", "\"\"");
    // Wrap the whole thing in double quotes.
    return '"' + out '"'
}

Use like this:

data.append(escapeCsv(pre_comments_consolidated));

Be mindful of

  • which quotes you need to denote a Java string,
  • which quotes you need printed literally,
  • which quotes need escaping (either in Java or in a format down the line, like CSV).
Eugen Pechanec
  • 37,669
  • 7
  • 103
  • 124