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

时间:2019-05-16 12:02:11

标签: java opencsv

使用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的选项,因为我必须将此方法构建为通用解决方案。 谁能建议我如何按原样编写标题?

3 个答案:

答案 0 :(得分:2)

之所以会这样,是因为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();

答案 1 :(得分:2)

实际上,HeaderColumnNameMappingStrategy uses toUpperCase()用于存储和检索字段名称。 为了使用自定义字段名称,您必须使用@CsvBindByName注释您的字段

public class Test extends AppCompatActivity {

RecyclerView recycler;
MenuAdapter adapter;
List<MenuModel> list = new ArrayList<>();
ProgressBar prog;

private static final String URL = "https://www.flypped.com/api/Categoery_api";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);

    recycler = findViewById(R.id.recycler);
    prog = findViewById(R.id.prog);
    recycler.setHasFixedSize(true);
    recycler.setLayoutManager(new LinearLayoutManager(this));

    getData();
}

private void getData(){

    OkHttpClient client = new OkHttpClient.Builder()
            .readTimeout(20, TimeUnit.SECONDS)
            .writeTimeout(20,TimeUnit.SECONDS)
            .build();

    Request request = new Request.Builder().url(URL).build();

    client.newCall(request).enqueue(new Callback() {

        @Override
        public void onResponse(@NotNull Call call, @NotNull final Response response) throws IOException {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    try {

                        JSONArray jsonArray =  new JSONArray(response.body().string());

                        if(jsonArray.length() > 0){

                            prog.setVisibility(View.INVISIBLE);

                            for(int i =0;i<jsonArray.length();i++){

                                JSONObject jsonObject = jsonArray.getJSONObject(i);

                                String str1 = jsonObject.getString("name");
                                String str2 = jsonObject.getString("term_id");

                                MenuModel model = new MenuModel(str1,str2);
                                list.add(model);
                            }

                            adapter = new MenuAdapter(list,getApplicationContext());
                            recycler.setAdapter(adapter);
                        }

                    } catch (JSONException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });

        }

        @Override
        public void onFailure(@NotNull Call call, @NotNull final IOException e) {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    prog.setVisibility(View.INVISIBLE);
                    Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
                }
            });
        }
    });
  }
}

由于上述原因,默认情况下它将大写为PARTNER CODE。 因此,为了控制它,我们必须编写一个实现HeaderColumnNameTranslateMappingStrategy的类。使用csv 5.0和java8,我已经实现了这样

@CsvBindByName(column = "Partner Code" )
private String partnerCode;

答案 2 :(得分:0)

使用opencsv 5.0和Java 8,我必须按如下所示修改AnnotationStrategy类代码以进行编译:

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import com.opencsv.bean.CsvBindByName;
import com.opencsv.bean.HeaderColumnNameTranslateMappingStrategy;
import com.opencsv.exceptions.CsvRequiredFieldEmptyException;

public class AnnotationStrategy<T> extends HeaderColumnNameTranslateMappingStrategy<T> {
    public AnnotationStrategy(Class<? extends T> 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(T bean) throws CsvRequiredFieldEmptyException {
        String[] result = super.generateHeader(bean);
        for (int i = 0; i < result.length; i++) {
            result[i] = getColumnName(i);
        }
        return result;
    }
}