仅使用OpenCSV部分解析CSV文件

时间:2016-02-29 08:56:41

标签: java parsing csv partial opencsv

我有一个CSV文件,我想用Java解析OpenCSV的csvreader。

为此,我创建了一个信息映射到的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是读数开始的行)

其他数据主要是文件末尾的(例如)整数列中的字符串。

例如,我有一个带有整数信息的“Max Speed”列,紧挨着带有整数信息的“Distance”列。但是在“距离”列的末尾有总距离,因此字符串“total:”位于其旁边的“最大速度”列中。

我该怎样做才能确保读者忽略最后一行并只读取上面的原始信息?

PS:我读过的CSV文件有不同的长度。所以说“在X行后停止阅读”将无法解决问题。另一方面,“附录”线总是相同的。所以说“在文件结尾之前停止阅读两行”应该可行。

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:2)

你可以总是降到较低级别并检查原始字符串数组,然后将其映射到bean中,如下所示:

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);
        }
    }

答案 1 :(得分:0)

如果您使用的是较新版本的opencsv,请将CsvToBeanFilter注入CSVtoBean类。 opencsv javadoc提供了如何创建过滤器的绝佳示例。对于您的示例,您只需创建一个过滤器,如果最大速度为空,空或&#34;总计:&#34;

,其allowLine方法将返回false