Opencsv、StatefulBeanToCsv 将嵌套的对象列表写入 csv

Opencsv, StatefulBeanToCsv write nested List of Objects to csv

提问人:Caffeine Coder 提问时间:4/1/2020 最后编辑:Caffeine Coder 更新时间:10/28/2023 访问量:3341

问:

我必须使用打开的csv将嵌套的对象列表(StoreLocations)写入Csv文件。 我的模型类是-

public class StoreLocation {
    private String name;
    private String city;
    private int zip;
    private String streetAndNumber;
    private List<String> keywords;
    private Double lat;
    private Double lng;
    private List<OpeningHours> openingHours;
}

public class OpeningHours {
    private String dayOfWeek;
    private String from1;
    private String to1;
}

我的写作方法——

public void getStoreLocationData(List<StoreLocation> storeLocations) throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
        try (
                Writer writer = Files.newBufferedWriter(Paths.get(storeLocationDataCsv))
        ) {
            StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer)
                    .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
                    .build();
            beanToCsv.write(storeLocations);
        }
    }

此代码可以完美地生成除开放时间列表之外的所有列。 这是当前的输出 -enter image description here 我宁愿有一列开放时间,并将每个开放时间安排为新行。 类似于enter image description here在营业时间列内的 json 列表中显示所有营业时间。 可能我需要columnPositionMappingStrategy来设置这些列,但我需要知道如何使用它?

这是数组位置列表的 json 表示形式 -

[{
"name":"OBI Markt Kempen",
"city":"Kempen",
"zip":47906,
"streetAndNumber":"Kleinbahnstraße 32",
"keywords":[],
"lat":51.3740233,
"lng":6.4182039,
"openingHours":
[{"dayOfWeek":"1","from1":"08:00","to1":"20:00"},
{"dayOfWeek":"2","from1":"08:00","to1":"20:00"},
]}]

注意:我尝试使用超级csv()引用使用OpenCSV将CSV解析为多个/嵌套的bean类型? ,它变得非常复杂,而且我也不明白如何将其写入文件。

此外,我已经参考了所有关于通过stackoverflow将复杂/嵌套的java对象编写到csv的文章。

java 列表 csv opencsv writetofile

评论


答:

0赞 kpgan8204 10/28/2023 #1
public class CustomMappingStrategy<T> extends ColumnPositionMappingStrategy<T> {

    public String[] generateHeader() {
        
            return new String[]{"name","city","zip",
           "streetAndNumber" ,"keywords","lat","lon","openingHrs_dayOfWeek","openingHrs_froml","openingHrs_to1"
          
        };
        
    }
    
    //override transmuteBean  or toString() in StoreLocation
        @Override
    public String[] transmuteBean(T bean) {
        // Override this method to handle nested objects
        if (bean instanceof StoreLocation ) {
            return toStringArray((StoreLocation) bean);
        } else {
            
            return new String[0]; 
        }
    }
    
    
    public String[] toStringArray(StoreLocation storeLocation) {
        return new String[] {
                String.valueOf(storeLocation.getName()),
        
                String.valueOf(storeLocation.getCity()),
                String.valueOf(storeLocation.getZip()),
                String.valueOf(storeLocation.getStreeAndNumber()),
                String.valueOf(storeLocation.getKeyWords().toString()),
                String.valueOf(storeLocation.getLat()),
                String.valueOf(storeLocation.getLon()),
                List<OpeningHours> openingHours = storeLocation.getOpeningHrs();
                for(OpeningHours obj: openingHours)
                { 
                String.valueOf(obj.getDayOfWeek()),
                String.valueOf(obj.getFrom1()),
                String.valueOf(obj.getTo1()),
                }
                
        
        };
    }
    
    }
    
    //use above strategy 
    
    public void getStoreLocationData(List<StoreLocation> storeLocations) throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
    
      CustomMappingStrategy<StoreLocation> strategy = new CustomMappingStrategy<>();
        String[] headers=strategy.generateHeader();
        strategy.setType(StoreLocation.class);
        strategy.setColumnMapping(headers);
       
        try (
                Writer writer = Files.newBufferedWriter(Paths.get(storeLocationDataCsv))
        ) {
            StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer)
                    .withMappingStrategy(mappingStrategy)
                    .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
                    .build();
            beanToCsv.write(storeLocations);
        }
    }