![](/img/trans.png)
[英]Return a JSON response as CSV file from spring-boot controller
[英]JSP and SPRING Boot : Generate CSV file from JSON input?
我做了一些研究,但是找不到解决方法。 当用户单击客户侧的“使用mailId导出记录时”,我希望能够从数据库中将一些记录导出到CSV。 实现此目标的最佳方法是什么? 在我的研究中,我发现人们仅使用Servlet作为示例,但对我而言,我不使用Servlet。
这是我的控制器:
@RequestMapping(value = "/eblnotif/exportMailId", method = RequestMethod.POST, produces = "application/json")
public @ResponseBody List<EblNotifResource> exportMailIdCsv(@RequestBody Filters filters)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
SecurityException, IOException {
List<EblNotif> eblnotif_list = accountSservice.exportMailIdCsv(filters);
List<EblNotifResource> eblnotifres = new ArrayList<>();
for (EblNotif eblNotif : eblnotif_list) {
EblNotifResource eblres = new EblNotifResource();
eblres.setFormName(eblNotif.getFormName());
eblres.setSendingDate(eblNotif.getSendingDate());
eblres.setMode(eblNotif.getMode());
eblres.setLanguage(eblNotif.getLanguage());
eblres.setGpart(eblNotif.getGpart());
eblres.setEmail(eblNotif.getEmail());
eblres.setMailId(eblNotif.getMailId());
eblnotifres.add(eblres);
}
return eblnotifres;
}
}
并将此json格式返回给客户端(JSP):
[
{
"formName":"FormName1",
"mode":"S",
"language":"F",
"sendingDate":"2017-04-03",
"gpart":"555",
"email":"",
"mailId":"96318"
},
{
"formName":"FormName2",
"mode":"S",
"language":"F",
"sendingDate":"2017-04-03",
"gpart":"444",
"email":"",
"mailId":"96325"
}
]
所需的csv输出如下所示:
formName;mode;language;sendingDate;gpart;email;mailId
FormName1;S;F;2017-04-03;555;testing@test;96318
FormName2;S;F;2017-04-03;444;testing@test;96325
如果只需要一次性下载CSV,则在控制器方法内部转换相关对象可能是最简单的选择。 但是,如果需要在多个位置进行这种下载,则将来通过HttpMessageConverter
向Spring MVC Rest添加CSV支持可能会更有益。
第1步 :可选,但建议
使用OpenCSV , uniVocity或Smooks (仅CSV解析器)之类的CSV转换库在CSV之间进行对象转换。 使用良好的库将节省大量样板代码,还可用于扩展对其他格式的支持,例如制表符分隔的值(TSV)和固定宽度的列。
步骤2 :实现
GenericHttpMessageConverter
创建GenericHttpMessageConverter
的实现,以使用在步骤1中选择的CSV转换库将对象与CSV相互转换。此步骤有点棘手,因为HttpMessageConverter
通常用于将单个对象转换为所需的内容类型,而CSV内容是对象的集合(每行代表一个对象)。 但是,Spring团队在Jaxb2CollectionHttpMessageConverter
提供了一个出色的示例,用于将对象的集合转换为所需的内容类型。 需要牢记以下几点:
boolean canRead(Class<?>, MediaType)
方法始终返回false
因为CSV内容是对象的集合,因此无法将其读取为类型指定的单个对象。 boolean canRead(Type, Class<?>, MediaType)
方法应检查Type
以确保它指定Collection
类型,并且还指定了期望该collection保留的元素类型。 T read(Type, Class<?>, HttpInputMessage)
方法来读取CSV内容。 void write(T, Type, Class<?>, HttpInputMessage)
方法来写入CSV内容。 步骤3 :CSV消息转换器应在配置中注册
@Override
protected void configureMessageConverters(final List<HttpMessageConverter<?>> converters)
{
converters.add(csvMessageConverter());
super.addDefaultHttpMessageConverters(converters);
}
步骤4 :应使用控制器方法来返回所需对象的集合
public List<?> get() { ... }
Github上有一个示例应用程序显示了这一功能。 启动应用程序,然后将请求发送到http://localhost:8080/persons.csv
或http://localhost:8080/persons.json
分别检索CSV或JSON格式的数据。
有多种方法可以转换为CSV,但一种方法
@RequestMapping(value = "/eblnotif/exportMailId", method = RequestMethod.POST, produces = "application/json")
public @ResponseBody String exportMailIdCsv(@RequestBody Filters filters) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, IOException {
List<EblNotif> eblnotif_list = accountSservice.exportMailIdCsv(filters);
String separator = ";";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
StringBuilder sb = new StringBuilder();
sb.append("formName;mode;language;sendingDate;gpart;email;mailId").append(System.lineSeparator());
for (EblNotif eblNotif : eblnotif_list) {
sb.append(eblNotif.getFormName()).append(separator);
sb.append(eblNotif.getMode()).append(separator);
sb.append(eblNotif.getLanguage()).append(separator);
sb.append(dateFormat.format(eblNotif.getSendingDate())).append(separator);
sb.append(eblNotif.getGpart()).append(separator);
sb.append(eblNotif.getEmail()).append(separator);
sb.append(eblNotif.getMailId()).append(separator);
sb.append(System.lineSeparator());
}
return sb.toString();
}
使用Apache Commons CSV,您可以执行以下操作:
@RequestMapping(value = "/download/eblnotif")
public void download(@RequestBody @Valid Filters filter,
HttpServletResponse httpServletResponse) throws Exception {
List<EblNotifResource> resources = //find from the fitler
CSVPrinter csvPrinter = CSVWriterUtil.transformResourcesToCSVPrinter(new BufferedWriter(httpServletResponse.getWriter()), resources);
httpServletResponse.setHeader("Content-Disposition", "attachment; filename=\"file.csv\"");
csvPrinter.flush();
csvPrinter.close();
}
public final class CSVWriterUtil {
private static final String NEW_LINE_SEPARATOR = "\n";
private CSVWriterUtil() {
}
public static CSVPrinter transformResourcesToCSVPrinter(Writer writer, List<EblNotifResource> eblNotifResources) {
try {
CSVPrinter csvPrinter = new CSVPrinter(new BufferedWriter(writer), CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR));
for (EblNotifResource eblNotifResource : eblNotifResources) {
List<String> dataRecords = new ArrayList<>();
dataRecords.add(eblNotifResource.getFormName());
dataRecords.add(eblNotifResource.getSendingDate());
//...etc
csvPrinter.printRecord(dataRecords);
}
return csvPrinter;
} catch (IOException e) {
throw new SystemException("Exception occurred while converting file", e);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.