如何使用 opencsv 编写 java csv 解析器

how to write java csv parser using opencsv

我必须解析 csv 文件。 列数是可变的。 我为固定列编写了以下代码。 我已经使用 csvtobean 和 MappingStrategy api 进行解析。

请帮助我如何动态创建映射。

public class OpencsvExecutor2 {

public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub

    CsvToBean csv = new CsvToBean();
    String csvFilename="C:\Users\ersvvwa\Desktop\taks\supercsv\20160511-0750--MaS_GsmrRel\20160511-0750--MaS_GsmrRel.txt";
    CSVReader csvReader = null;
    List objList=new ArrayList<DataBean>();
    try {


        FileInputStream fis = new FileInputStream(csvFilename);       
        BufferedReader myInput = new BufferedReader(new InputStreamReader(fis));            

        csvReader = new CSVReader(new InputStreamReader(new FileInputStream(csvFilename), "UTF-8"), ' ', '\'', 1);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    csvReader.getRecordsRead();
    //Set column mapping strategy
      List<DataBean> list = csv.parse(setColumMapping(csvReader), csvReader);
      for (Object object : list) {
          DataBean obj = (DataBean) object;
         // System.out.println(obj.Col1);
          objList.add(obj);
      }

      csvReader.close();

      System.out.println("list size "+list.size());
      System.out.println("objList size "+objList.size());
      String outFile="C:\Users\ersvvwa\Desktop\taks\supercsv\20160511-0750--MaS_GsmrRel\20160511-0750--MaS_GsmrRel.csv";
      try {

         CSVWriter csvWriter = null;
         csvWriter = new CSVWriter(new FileWriter(outFile),CSVWriter.DEFAULT_SEPARATOR,CSVWriter.NO_QUOTE_CHARACTER);
         //csvWriter = new CSVWriter(out,CSVWriter.DEFAULT_SEPARATOR,CSVWriter.NO_QUOTE_CHARACTER);
         String[] columns = new String[] {"col1","col2","col3","col4"};
        // Writer w= new FileWriter(out);

         BeanToCsv bc = new BeanToCsv();    

         List ls;
         csvWriter.writeNext(columns);



        //bc.write(setColumMapping(), csvWriter, objList);
        System.out.println("complete");
        csvWriter.close();  

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private static MappingStrategy setColumMapping(CSVReader csvReader) throws IOException {
    // TODO Auto-generated method stub
    ColumnPositionMappingStrategy strategy = new ColumnPositionMappingStrategy();
      strategy.setType(DataBean2.class);
      String[] columns = new String[] {"col1","col2","col3","col4"};
      strategy.setColumnMapping(columns);


      return strategy;
}

}

如果我没理解错的话,你可以逐行阅读文件并使用split

示例 READ CSV:从 mkyong

中提取的示例
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class ReadCVS {

  public static void main(String[] args) {

  ReadCVS obj = new ReadCVS();
  obj.run();

  }

  public void run() {

  String csvFile = "/Users/mkyong/Downloads/GeoIPCountryWhois.csv";
  BufferedReader br = null;
  String line = "";
  String cvsSplitBy = ",";

  try {

    br = new BufferedReader(new FileReader(csvFile));
    while ((line = br.readLine()) != null) {

            // use comma as separator
      String[] country = line.split(cvsSplitBy);

      System.out.println("Country [code= " + country[4] 
                                 + " , name=" + country[5] + "]");

    }

  } catch (FileNotFoundException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    if (br != null) {
      try {
        br.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  System.out.println("Done");
  }

}

写入 CSV 文件的示例:从 mkyong

中提取的示例
import java.io.FileWriter;
import java.io.IOException;

public class GenerateCsv
{
   public static void main(String [] args)
   {
     generateCsvFile("c:\test.csv"); 
   }

   private static void generateCsvFile(String sFileName)
   {
  try
  {
      FileWriter writer = new FileWriter(sFileName);

      writer.append("DisplayName");
      writer.append(',');
      writer.append("Age");
      writer.append('\n');

      writer.append("MKYONG");
      writer.append(',');
      writer.append("26");
            writer.append('\n');

      writer.append("YOUR NAME");
      writer.append(',');
      writer.append("29");
      writer.append('\n');

      //generate whatever data you want

      writer.flush();
      writer.close();
  }
  catch(IOException e)
  {
       e.printStackTrace();
  } 
    }
} 

不过,我建议使用图书馆。有很多(例如,opencsv、Apache Commons CSV、Jackson Dataformat CSV 等)。您不必重新发明轮子。

  • OPENCSV 网站有很多示例可供您使用。
  • 如果您 Google "opencsv read example" 您将获得大量使用 OPENCSV 库的示例(例如,"Parse / Read / write CSV files : OpenCSV tutorial")

希望对您有所帮助!

假设您的代码有效,我会尝试对 setColumnMapping 方法使用泛型。

方法 setType 获取一个参数 "Class type"。将其用作您自己的方法 setColumnMapping 的参数,例如 (CSVReader csvReader, Class type)。这样您就可以将 DataBean2.class 或任何其他 class 传递给方法。此外,您需要一个可变列到 bean 映射,因为 {"col1","col2","col3","col4"} 对每个 bean 都不够,如您所知。考虑如何使它动态化(例如,您可以将 String[] 传递给 setColumnMethod)。

您显然还需要调整 main 中的 List 用法。

我建议您在开始编程之前查找有关 java 泛型的简短教程。

最后我能够解析 csv 并将其写入所需的格式,如

 csvWriter = new CSVWriter(new    FileWriter(outFile),CSVWriter.DEFAULT_SEPARATOR,CSVWriter.NO_QUOTE_CHARACTER);
    csvReader = new CSVReader(new InputStreamReader(new FileInputStream(csvFilename), "UTF-8"), ' ');
    String header = "NW,MSC,BSC,CELL,CELL_0";
    List<String> headerList = new ArrayList<String>();
    headerList.add(header);
    csvWriter.writeNext(headerList.toArray(new String[headerList.size()]));
    while ((nextLine = csvReader.readNext()) != null) {
        // nextLine[] is an array of values from the line

        for(int j=0;j< nextLine.length;j++){
            // System.out.println("next " +nextLine[1]+" "+nextLine [2]+ " "+nextLine [2]);
            if(nextLine[j].contains("cell")|| 
                    nextLine[j].equalsIgnoreCase("NW") ||
                    nextLine[j].equalsIgnoreCase("MSC") ||
                    nextLine[j].equalsIgnoreCase("BSC") ||
                    nextLine[j].equalsIgnoreCase("CELL")){
                hm.put(nextLine[j], j);
            }

        }

        break;
    }

    String[] out=null;

    while ((row = csvReader.readNext()) != null) {

        String [] arr=new String[4];

        outList = new ArrayList<>();
        innerList = new ArrayList<>();
        finalList=new ArrayList<String[]>();
        String[] str=null;

        int x=4;
        for(int y=0; y<hm.size()-10;y++){               

            if(!row[x].equalsIgnoreCase("NULL")|| !row[x].equals(" ")){
                System.out.println("x "+x);
                str=new String[]{row[0],row[1],row[2],row[3],row[x]};
            }

            finalList.add(str);;

            x=x+3;

        }
        csvWriter.writeAll(finalList);

        break;


    }

    csvReader.close();
    csvWriter.close();


}