网络彩票网站建设,企业网上推广方式,衡水哪有建网站的吗,广州互帮物流哪家公司做的网站问题情景#xff1a;
最近项目中遇到了根据第三方系统传递过来的参数#xff0c;封装为List实体类对象后#xff0c;将该实体类转换为csv文件#xff0c;然后上传到远程的sftp服务器指定目录的需求。
实现思路#xff1a;
List实体类对象转为csv文件的…问题情景
最近项目中遇到了根据第三方系统传递过来的参数封装为List实体类对象后将该实体类转换为csv文件然后上传到远程的sftp服务器指定目录的需求。
实现思路
List实体类对象转为csv文件的过程。通过OpenCsv实现。
阻塞点
1.最开始遇到了生成的csv文件的第一行生成的字段名变成了实体类的大写字段名了例如userName变为USERNAME并且排序混乱。 2.通过查阅资料找到了以下两个注解后期却发现两个注解不能同时出现。详见文章 为什么 opencsv 在写入文件时将 csv 标头大写
CsvBindByName(column TradeID)
CsvBindByPosition(position 0)解决方案
方案一 创建自定义MappingStrategy
class CustomMappingStrategy extends ColumnPositionMappingStrategy { private static final String[] HEADER new String[]{“TradeID”, “GWML GUID”, “MXML GUID”, “GWML File”, “MxML File”, “MxML Counterparty”, “GWML Counterparty”};
Override
public String[] generateHeader() {return HEADER;
}} 并在StatefulBeanToCsvBuilder使用它
final CustomMappingStrategy mappingStrategy new CustomMappingStrategy(); mappingStrategy.setType(MappingsBean.class);
final StatefulBeanToCsv beanToCsv new StatefulBeanToCsvBuilder(writer) .withMappingStrategy(mappingStrategy) .build(); beanToCsv.write(makeFinalMappingBeanList()); writer.close() 在MappingsBean类中我们留下了CsvBindByPosition注释 - 以控制排序在此解决方案中 CsvBindByName注释。 由于自定义映射策略标题列名称包含在生成的 CSV 文件中。
此解决方案的缺点是当我们通过CsvBindByPosition注释更改列顺序时我们必须手动更改自定义映射策略中的HEADER常量。
方案二 该方案可以根据实体类字段名称生成CSV第一行注意一定不要加CsvBindByName注解具体文章可以参考opencsv 将对象数组导出为 csv 文件时、文件列按对象字段定义顺序排序的实现
SneakyThrows
public T String generateCsvFile(List? extends T exportResults, String fileName)throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {String finalFileName new File(nginxDownloadPath,fileName System.currentTimeMillis() .csv).getPath();Writer writer new FileWriter(finalFileName);CSVWriter csvWriter new CSVWriter(writer,CSVWriter.DEFAULT_SEPARATOR,CSVWriter.DEFAULT_QUOTE_CHARACTER,CSVWriter.NO_ESCAPE_CHARACTER,CSVWriter.DEFAULT_LINE_END);csvWriter.writeNext(header);if (exportResults.size() 0) {//写内容StatefulBeanToCsv beanToCsv new StatefulBeanToCsvBuilderT(writer).withMappingStrategy(new OrderColumnMappingStrategy(exportResults.get(0).getClass())).withIgnoreField(exportResults.get(0).getClass(), Arrays.stream(exportResults.get(0).getClass().getDeclaredFields()).filter(one - {one.setAccessible(true);return one.isAnnotationPresent(CsvIgnore.class);}).findFirst().orElse(null)).build();beanToCsv.write(exportResults);}csvWriter.close();writer.close();return finalFileName;
}public class OrderColumnMappingStrategyT extends HeaderColumnNameMappingStrategyT {private Locale errorLocale Locale.getDefault();public OrderColumnMappingStrategy(Class? extends T type) {super();this.setErrorLocale(errorLocale);this.setType(type);}Overridepublic String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {if (type null) {throw new IllegalStateException(ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString(type.before.header));}if (headerIndex.isEmpty()) {ListString realHeaderList new ArrayList();/**getFieldNameForCsvHeader()方法是通过反射获取对象的字段, 字段是按照定义顺序返回的. 这里就不贴出代码了*/getFieldNameForCsvHeader(type).forEach(one - {realHeaderList.add(one.toUpperCase());});String[] header realHeaderList.toArray(new String[0]);headerIndex.initializeHeaderIndex(header);return header;}return headerIndex.getHeaderIndex();}
}