有没有一种方法可以在使用Jackson处理CSV文件时跳过不需要的字段?

huangapple go评论84阅读模式
英文:

Is there a way to skip unwanted fields in a CSV file with Jackson?

问题

我有一些包含多列的CSV文件,但我只需要导入其中的一些列。问题在于这些列有的在开头,有的在中间,有的在末尾,就像这样:

id;name;address;bla;bla;bla;status;bla;bla;bla;value;another_value

我想要创建一个仅包含必要字段的对象,例如:

long id;
String address;
boolean status;
double value;
double another_value;

问题是这些文件有79列,我不想编写一个包含79个属性的类,而只使用其中的一些属性。

英文:

I have some CSV files with several columns, but I just need to import some of these columns. The problem is that there are some columns at the beginning, some in the middle and some at the end of the line, like this:

id;name;address;bla;bla;bla;status;bla;bla;bla;value;another_value

And I want to write an object with only the necessary fields, like:

long id;
String address;
boolean status;
double value;
double another_value;

The problem is that these files have 79 columns, and I don't want to write a class with 79 properties and use only some of these properties.

答案1

得分: 0

可能更容易的方法是只需将其转换为 String[],然后编写一些代码将其转换为对象。

英文:

It may be easier to just make a conversion to String[] and then write some code to convert into into an object.

答案2

得分: 0

你可以将整行反序列化为一个 Map,然后将其转换为所需的 POJO。下面是一个示例:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import lombok.Data;
import lombok.ToString;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class CsvApp {

    public static void main(String[] args) throws Exception {
        File csvFile = new File("./resource/test.csv").getAbsoluteFile();

        CsvMapper csvMapper = CsvMapper.builder()
                //ignore unknown columns
                .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
                .build();

        CsvSchema schema = CsvSchema.emptySchema().withHeader().withColumnSeparator(';');
        MappingIterator<Map> rowsIterator = csvMapper
                .readerWithSchemaFor(Map.class)
                .with(schema)
                .readValues(csvFile);

        List<Row> rows = new ArrayList<>();
        while (rowsIterator.hasNext()) {
            Map rowAsMap = rowsIterator.next();
            Row row = csvMapper.convertValue(rowAsMap, Row.class);
            rows.add(row);
        }

        rows.forEach(System.out::println);
    }
}

@Data
@ToString
class Row {
    long id;
    String address;
    boolean status;
    double value;
    double another_value;
}

我使用了 Lombok 库来使示例更加简洁,但你不一定需要使用它。

对于以下 CSV 数据:

id;name;address;bla1;bla2;bla3;status;bla4;bla5;bla6;value;another_value
33;Jack;Cave Street;1;2;3;true;4;5;6;123;234

上面的代码将打印出:

Row(id=33, address=Cave Street, status=true, value=123.0, another_value=234.0)
英文:

You can deserialise the whole row to a Map and after that convert it to a required POJO. Below you can find an example:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import lombok.Data;
import lombok.ToString;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class CsvApp {
public static void main(String[] args) throws Exception {
File csvFile = new File(&quot;./resource/test.csv&quot;).getAbsoluteFile();
CsvMapper csvMapper = CsvMapper.builder()
//ignore unknown columns
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();
CsvSchema schema = CsvSchema.emptySchema().withHeader().withColumnSeparator(&#39;;&#39;);
MappingIterator&lt;Map&gt; rowsIterator = csvMapper
.readerWithSchemaFor(Map.class)
.with(schema)
.readValues(csvFile);
List&lt;Row&gt; rows = new ArrayList&lt;&gt;();
while (rowsIterator.hasNext()) {
Map rowAsMap = rowsIterator.next();
Row row = csvMapper.convertValue(rowAsMap, Row.class);
rows.add(row);
}
rows.forEach(System.out::println);
}
}
@Data
@ToString
class Row {
long id;
String address;
boolean status;
double value;
double another_value;
}

I used Lombok library to make an example short but you do not have to use it.

For below CSV payload:

id;name;address;bla1;bla2;bla3;status;bla4;bla5;bla6;value;another_value
33;Jack;Cave Street;1;2;3;true;4;5;6;123;234

Above code prints:

Row(id=33, address=Cave Street, status=true, value=123.0, another_value=234.0)

huangapple
  • 本文由 发表于 2020年7月30日 01:43:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63159490.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定