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