Warm tip: This article is reproduced from serverfault.com, please click

java-为什么 opencsv 在写入文件时将 csv 标头大写

(java - Why opencsv capitalizing csv headers while writing to file)

发布于 2019-05-16 12:02:10

使用 OpenCSV 4.6 将 Beans 写入 CSV 文件时,所有标头都更改为大写。尽管 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"

直接结果:

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

我没有使用 ColumnMappingStrategy 的选项,因为我必须将此方法构建为通用解决方案。谁能建议我如何按原样编写标题?

Questioner
prasadg
Viewed
0
Sascha 2021-08-28 16:34:57

发生这种情况是因为 HeaderColumnNameMappingStrategy 中的代码用于存储和检索字段名称。toUpperCase()

你可以改用 HeaderColumnNameTranslateMappingStrategy,并通过反射创建映射。

    
    public class AnnotationStrategy extends HeaderColumnNameTranslateMappingStrategy
    {
        public AnnotationStrategy(Class<?> clazz)
        {
            Map<String,String> map=new HashMap<>();
            //To prevent the column sorting
            List<String> originalFieldOrder=new ArrayList<>();
            for(Field field:clazz.getDeclaredFields())
            {
                CsvBindByName annotation = field.getAnnotation(CsvBindByName.class);
                if(annotation!=null)
                {
                    map.put(annotation.column(),annotation.column());
                    originalFieldOrder.add(annotation.column());
                }
            }
            setType(clazz);
            setColumnMapping(map);
            //Order the columns as they were created
            setColumnOrderOnWrite((a,b) -> Integer.compare(originalFieldOrder.indexOf(a), originalFieldOrder.indexOf(b)));
        }
        
        @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();