2016-02-29 75 views
0

我有一個CSV文件,我想用OpenCSV的csvreader在Java中解析。只使用OpenCSV部分解析CSV文件

爲此,我創建了一個信息映射到的bean對象。煤礦是有點長,所以這裏有一個例子,我從一個教程了:

package net.viralpatel.java; 

public class Country { 
    private String countryName; 
    private String capital; 

    public String getCountryName() { 
    return countryName; 
    } 

    public void setCountryName(String countryName) { 
     this.countryName = countryName; 
    } 

    public String getCapital() { 
     return capital; 
    } 

    public void setCapital(String capital) { 
     this.capital = capital; 
    } 
} 

我用來分析我的CSV文件和地圖信息的bean代碼類似於這樣:

ColumnPositionMappingStrategy strat = new ColumnPositionMappingStrategy(); 
strat.setType(Country.class); 
String[] columns = new String[] {"countryName", "capital"}; 
strat.setColumnMapping(columns); 

CsvToBean csv = new CsvToBean(); 

String csvFilename = "C:\\sample.csv"; 
CSVReader csvReader = new CSVReader(new FileReader(csvFilename)); 

List list = csv.parse(strat, csvReader); 

的問題在於我的CSV不僅包含原始數據,還包含列標題和其他數據。對於列標題,我只從某行讀我的文件,解決了這個問題:

CSVReader csvReader = new CSVReader(new FileReader(csvFilename), ';', '\'', 1); 

(1爲從中讀始於行)

的其他數據大多在字符串(例如)文件末尾的整數列。

例如我有一個整數信息的「最大速度」列,就在整數信息的「距離」列旁邊。但在「距離」列末尾有總距離,所以字符串「total:」位於它旁邊的「最大速度」列中。

我該怎麼做才能確保讀者忽略最後幾行並只讀取上面的原始信息?

PS:我讀取的CSV文件有不同的長度。所以說「在X行之後停止閱讀」不會成功。另一方面,「附錄」行總是相同的。所以說「在文件結束之前停止閱讀兩行」應該可行。

非常感謝您的幫助。

回答

1

你總是可以下降到較低的水平和地圖之前檢查原始字符串數組豆這樣的:

ColumnPositionMappingStrategy<Country> strat = new ColumnPositionMappingStrategy<Country>(); 
    strat.setType(Country.class); 
    String[] columns = new String[] {"countryName", "capital"}; 
    strat.setColumnMapping(columns); 

    PublicProcessLineCsvToBean<Country> csv = new PublicProcessLineCsvToBean<Country>(); 

    String csvFilename = "C:\\sample.csv"; 
    CSVReader csvReader = new CSVReader(new FileReader(csvFilename)); 
    List<Country> list = new ArrayList<Country>(); 

    String [] row = csvReader.readNext(); //skip header 
    if(row == null) throw new RuntimeException("File is empty"); 
    row = csvReader.readNext(); 
    String [] nextRow = csvReader.readNext(); 
    while(row != null) { 
     if(nextRow == null) break; //check what 'row' is last 
     if("Total:".equalsIgnoreCase(row[1])) break; //check column for special strings 

     list.add(csv.processLine(strat, row)); 

     row = nextRow; 
     nextRow = csvReader.readNext(); 
    } 

並作出ProcessLine從公衆:

public static class PublicProcessLineCsvToBean<T> extends CsvToBean<T> { 

     @Override 
     public T processLine(MappingStrategy<T> mapper, String[] line) throws IllegalAccessException, InvocationTargetException, InstantiationException, IntrospectionException { 
      return super.processLine(mapper, line); 
     } 
    } 
+0

感謝您的幫助,但我有一個小問題「list.add(csv .processLine(strat,row));「線。我收到以下錯誤:「類型列表中的方法添加(國家)不適用於參數(對象)」和「來自類型CsvToBean的方法processLine(MappingStrategy ,String [])不可見」。你知道一種解決方法嗎? – markus

+0

我錯過了processLine的保護。查看更新的代碼。你也應該添加通用參數到MappingStrategy和CsvToBean聲明 – Andrew

+0

非常感謝你,你幫了我很多! – markus

0

如果您使用的是較新的opencsv的版本,然後注入一個CsvToBeanFilter到你的CSVtoBean類。 opencsv javadoc給出瞭如何創建過濾器的一個很好的例子。對於你的例子,你只是創建一個過濾器,其allowLine方法將返回false,如果最大速度爲空,空或「總:」