Modifying complex csv files in java

I wanted to write a program that can print and modify irregular csv files. The format looks like this:

    1.date
    2.organization name
    3. student name, id number, residence
       student name, id number, residence
       student name, id number, residence
       student name, id number, residence
       student name, id number, residence
    1.another date
    2.another organization name
    3. student name, id number, residence
       student name, id number, residence
       student name, id number, residence
      ..........

      

For example, data can be specified as follows:

1. 10/09/2016
2. cycling club
3. sam, 1000, oklahoma
   henry, 1001, california
   bill, 1002, NY
1. 11/15/2016
2. swimming club
3. jane, 9001, georgia
   elizabeth, 9002, lousiana

      

I'm a newbie and I haven't found a viable resource on the internet that tackles this type of problem. My main concern is how do we iterate over the loop and identify the date and club name and feed them into an array? Please advise.

+2


source to share


2 answers


I think this should be helpful to you. Basically, there should be some boilerplate in your messed up csv. Below is my code to arrange your csv

   public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {

        PrintWriter writer = new PrintWriter("file.txt", "UTF-8");
            try{

              //Create object of FileReader
              FileReader inputFile = new FileReader("csv.txt");

              //Instantiate the BufferedReader Class
              BufferedReader bufferReader = new BufferedReader(inputFile);

              //Variable to hold the one line data
              String line;
              String date="";String org ="";String student ="";
              // Read file line by line and print on the console
              while ((line = bufferReader.readLine()) != null)   {
                  if(line.contains("1.")){
                      if(date!="" || org!=""){
                          writer.println(date+","+org+","+student);
                          student ="";
                       }
                         date = line.substring(2);
                        }else if(line.contains("2.")){
                            org = line.substring(2);

                      }else{
                            line = "("+line+")";
                          student += line+",";
                  }

                    System.out.println(line);
              }
              writer.println(date+","+org+","+student);
              //Close the buffer reader
              bufferReader.close();
      }catch(Exception e){
        System.out.println("Error while reading file line by line:" + e.getMessage());                      
   }
       writer.close();
  }

      

This is the output you get for this



   10/09/2016, cycling club,(3. sam, 1000, oklahoma),(   henry, 1001, california),(   bill, 1002, NY),
   11/15/2016, swimming club,(3. jane, 9001, georgia),(   elizabeth, 9002, lousiana),

      

I am reading a file from csv.txt. while the loop goes through each line of the text file. All fields are stored in a variable. When the next date comes, I write them all to the output file. The last csv line is written to the file after the while loop ends.

+1


source


Try uniVocity-parsers to deal with this. For parsing this format, you will find several examples here . For writing see here and here .

Adapting from the above examples, you can write:



final ObjectRowListProcessor dateProcessor = new ObjectRowListProcessor();
final ObjectRowListProcessor clubProcessor = new ObjectRowListProcessor();
final ObjectRowListProcessor memberProcessor = new ObjectRowListProcessor();

InputValueSwitch switch = new InputValueSwitch(0){
    public void rowProcessorSwitched(RowProcessor from, RowProcessor to) {
    //your custom logic here
    if (to == dateProcessor) {
        //processing dates.
    }
    if (to == clubProcessor) {
        //processing clubs.
    }
    if (to == memberProcessor){
        //processing members
    }
};

switch.addSwitchForValue("1.", dateProcessor, 1);  //getting values of column 1 and sending them to `dateProcessor`
switch.addSwitchForValue("2.", clubProcessor, 1); //getting values of column 1 and sending them to `clubProcessor`
switch.addSwitchForValue("3.", memberProcessor, 1, 2, 3); //getting values of columns 1, 2, and 3 and sending them to `memberProcessor` 
setDefaultSwitch(memberProcessor, 1, 2, 3); //Rows with blank value at column 0 are members. Also get columns 1, 2, and 3 and send them to `memberProcessor`

CsvParserSettings settings = new CsvParserSettings(); //many options here, check the tutorial and examples

// configure the parser to use the switch
settings.setRowProcessor(switch);

//creates a parser
CsvParser parser = new CsvParser(settings);

//parse everying. Rows will be sent to the RowProcessor of each switch, depending on the value at column 0.
parser.parse(new File("/path/to/file.csv")); 

      

Disclaimer: I am the author of this library, open source and free (Apache 2.0 license)

+1


source







All Articles