Почему opencsv использует заглавные буквы csv при записи в файл - PullRequest
1 голос
/ 16 мая 2019

При записи Beans в файл CSV с помощью OpenCSV 4.6 все заголовки меняются на верхний регистр.Eventhough bean-компонент имеет аннотацию @CsvBindByName, которая изменяется на верхний регистр.

Java Bean:

public class ProjectInfo implements Serializable {

    @CsvBindByName(column = "ProjectName",required = true)
    private String projectName;

    @CsvBindByName(column = "ProjectCode",required = true)
    private String projectCode;

    @CsvBindByName(column = "Visibility",required = true)
    private String visibility;
    //setters and getters
}

Основной метод

public static void main(String[] args) throws IOException {
    Collection<Serializable> projectInfos = getProjectsInfo();
    try(BufferedWriter writer = new BufferedWriter(new FileWriter("test.csv"))){
        StatefulBeanToCsvBuilder builder = new StatefulBeanToCsvBuilder(writer);
        StatefulBeanToCsv beanWriter = builder
                    .withSeparator(';')
                    .build();
        try {
              beanWriter.write(projectInfos.iterator());
              writer.flush();

         } catch (CsvDataTypeMismatchException | CsvRequiredFieldEmptyException  e) {
                throw new RuntimeException("Failed to download admin file");
            }
        }

    }

Ожидаемый результат:

"ProjectCode";"ProjectName";"Visibility"
"ANY";"Country DU";"1"
"STD";"Standard";"1"
"TST";"Test";"1"
"CMM";"CMMTest";"1"

Acutal Result:

"PROJECTCODE";"PROJECTNAME";"VISIBILITY"
"ANY";"Country DU";"1"
"STD";"Standard";"1"
"TST";"Test";"1"
"CMM";"CMMTest";"1"

У меня нет возможности использовать ColumnMappingStrategy, потому что мне нужно построить этот метод как универсальное решение.Может кто-нибудь предложить мне, как написать заголовки, как это?

1 Ответ

2 голосов
/ 16 мая 2019

Это происходит потому, что код HeaderColumnNameMappingStrategy использует toUpperCase() для хранения и извлечения имен полей.

Вместо этого можно использовать HeaderColumnNameTranslateMappingStrategy и создать отображение по отражению.


    public class AnnotationStrategy extends HeaderColumnNameTranslateMappingStrategy
    {
        public AnnotationStrategy(Class<?> clazz)
        {
            Map<String,String> map=new HashMap<>();
            for(Field field:clazz.getDeclaredFields())
            {
                CsvBindByName annotation = field.getAnnotation(CsvBindByName.class);
                if(annotation!=null)
                {
                    map.put(annotation.column(),annotation.column());
                }
            }
            setType(clazz);
            setColumnMapping(map);
        }

        @Override
        public String[] generateHeader(Object bean) throws CsvRequiredFieldEmptyException
        {
            String[] result=super.generateHeader(bean);
            for(int i=0;i<result.length;i++)
            {
                result[i]=getColumnName(i);
            }
            return result;
        }
    }

И, предполагая, что существует только один класс предметов (и всегда хотя бы один предмет), создание beanWriter должно быть расширено:

StatefulBeanToCsv beanWriter = builder.withSeparator(';')
    .withMappingStrategy(new AnnotationStrategy(projectInfos.iterator().next().getClass()))
    .build();
...