复杂 Java 对象到 CSV
Complex Java object to CSV
我正在尝试从相当复杂的 Java 对象生成 CSV 文件。该对象是一个具有一些属性的会话和一个字符串列表,消息列表又具有一些属性和一个具有一些属性的注释列表。
本期class如下;
public class Session {
private Long id;
private Date startDate;
private Date endDate;
private List<Message> messages;
private List<String> participants;
public TweetSession() {
}
public TweetSession(Date startDate, List<Message> messages, List<String> participants) {
this.startDate = startDate;
this.messages = messages;
this.participants = participants;
}
public Long getId() {
return id;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public List<Message> getMessages() {
return messages;
}
public void setMessage(List<Message> messages) {
this.message = message;
}
public List<String> getParticipants() {
return participants;
}
public void setParticipants(List<String> participants) {
this.participants = participants;
}
}
留言class如下;
public class Message {
private Long id;
private Session session;
private Date date;
private String participant;
private String content;
private List<Comment> comments;
public Message() {
}
public Message(String participant, Session session, Date date, String content) {
this.participant = participant;
this.session = session;
this.content = content;
this.date = date;
this.comments = new ArrayList<>();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getParticipant() {
return participant;
}
public void setParticipant(String participant) {
this.participant = participant;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
public void addComment(Comment comment) {
this.comments.add(comment);
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public TweetSession getSession() {
return session;
}
public void setSession(TweetSession session) {
this.session = session;
}
}
和评论 class;
public class Comment {
private Long id;
private Message message;
private String participant;
private String message;
private Date date;
public Comment() {
}
public Comment(String participant, Message message, String content, Date date) {
this.participant = participant;
this.content = content;
this.message = message;
this.date = date;
}
public String getParticipant() {
return participant;
}
public void setParticipant(String participant) {
this.participant = participant;
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
我想知道是否可以将其映射到 CSV 文件。当我将会话对象转换为 JSON 格式并在在线生成器中将 JSON 转换为 CSV 时,我得到了正确的输出,所以我认为这一定是可能的。我只是真的不知道该怎么做。
我试过像这样使用 net.sf.supercsv 库;
public void generateCSV(Session session, HttpServletResponse response) throws IOException {
String csvFileName = "session.csv";
response.setContentType("text/csv");
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"",
csvFileName);
response.setHeader(headerKey, headerValue);
ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(),
CsvPreference.STANDARD_PREFERENCE);
// Generate header for the CSV
Field fields[] = session.getClass().getDeclaredFields();
String[] header = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
header[i] = fields[i].getName();
}
csvWriter.writeHeader(header);
// Generate CSV content from data
csvWriter.write(session, header);
csvWriter.close();
}
但这当然不会得到想要的结果。
任何人都可以指出我正确的方向吗?
提前致谢,
尼尔斯
编辑:
这是 JSON 格式的示例会话:
{
"id": 22,
"startDate": 1447368081000,
"endDate": null,
"messages": [
{
"id": 10,
"date": 1447368159000,
"participant": "1",
"content": "This is a message",
"comments": []
},
{
"id": 11,
"date": 1447368168000,
"participant": "1",
"content": "This is also a message",
"comments": []
},
{
"id": 12,
"date": 1447368179000,
"participant": "1",
"content": "This is another message",
"comments": [
{
"id": 10,
"participant": "1",
"message": "This is a comment",
"date": 1447368227000
},
{
"id": 11,
"participant": "1",
"message": "This is also a comment",
"date": 1447368234000
}
]
}
],
"participants": [
"1",
"23"
]
}
当我将其转换为 CSV 时,我得到如下信息:
确实开始考虑(单个)CSV 可能不是解决此问题的最佳方法。
我们使用了 openCSV
com.opencsv.bean.BeanToCsv to achieve this
public void exportIronData(String destinationFilePath,
List<ExportIronDataFileFormatDTO> dataList) throws Exception {
try {
if (validationUtil.isNullOrEmpty(destinationFilePath)
|| validationUtil.isNullOrEmpty(dataList)) {
return;
}
ColumnPositionMappingStrategy<ExportIronDataFileFormatDTO> strategy = new ColumnPositionMappingStrategy<ExportIronDataFileFormatDTO>();
strategy.setType(ExportIronDataFileFormatDTO.class);
String[] columns = IlmcrCsvFileConstants.EXPORT_IRONDATA_COLUMN_HEADERS;
strategy.setColumnMapping(columns);
CSVWriter writer = new CSVWriter(
new FileWriter(destinationFilePath),
IlmcrCsvFileConstants.exportIronDataSeperator,
CSVWriter.NO_ESCAPE_CHARACTER, System.getProperty("line.separator"));
BeanToCsv<ExportIronDataFileFormatDTO> exportFormat = new BeanToCsv<ExportIronDataFileFormatDTO>();
exportFormat.write(strategy, writer, dataList);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
如果您还需要什么,请告诉我
我建议改用 Apache Commons CSV。我们已经在几个项目中使用它,包括管理我们的邮件列表。
Reader in = new StringReader("a,b,c");
for (CSVRecord record : CSVFormat.DEFAULT.parse(in)) {
for (String field : record) {
System.out.print("\"" + field + "\", ");
}
System.out.println();
}
Output: "a", "b", "c",
您拥有的数据有许多 1:n 依赖项,并不适合 单个 CSV 文件。
我已经使用或看到用于此的方法:
一个 "hybrid" CSV 包含 Session
自己的数据,即第一列中的 id
、startDate
、endDate
和然后两列消息和参与者打印为 JSON
"123", "2015-11-17", "2015-11-18", "[{id: 345, date: ...}, {id: 789, date: ...}]", "[...]"
(注意你需要使用一个很好的 CSV 库来转义包含 ,
或 "
s 的值)
多个 CSV 文件 - 建模就像您为您的结构建模关系数据库,即
- sessions.csv 包含
id
、startDate
、endDate
- messages.csv 包含
id
、session_id
、date
、...
- ...
然后将它们压缩为单个文件下载
- 向您的用户询问更精确的规范 - 努力找出他们打算如何处理数据,然后以一种使他们能够轻松阅读的格式向他们提供 "view" 数据- 正是创建数据库视图和报告的方式为用户提供面向任务的数据视图。
您应该使用混合 CSV 格式。我遇到了同样的问题,所以我创建了一个轻量级框架。您可以从以下位置复制源代码或示例:https://github.com/abhisoni96/dev-tools
您可以为每个基于集合的数据成员创建自己的格式化程序。请参考上面的例子 link.
有一个库叫做 json2flat.
它所做的是获取一个复杂的 JSON 文档并将其转换为 CSV 格式。
所以您需要做的是将您的 java 对象转换为 JSON 格式。之后
您需要将生成的 JSON 传递到库中,它 returns 一个 2D
JSON 的表示,您还可以从中获取 csv。
这个库不是那么成熟,但仍然很有前途。
你应该试试看。
我正在尝试从相当复杂的 Java 对象生成 CSV 文件。该对象是一个具有一些属性的会话和一个字符串列表,消息列表又具有一些属性和一个具有一些属性的注释列表。
本期class如下;
public class Session {
private Long id;
private Date startDate;
private Date endDate;
private List<Message> messages;
private List<String> participants;
public TweetSession() {
}
public TweetSession(Date startDate, List<Message> messages, List<String> participants) {
this.startDate = startDate;
this.messages = messages;
this.participants = participants;
}
public Long getId() {
return id;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public List<Message> getMessages() {
return messages;
}
public void setMessage(List<Message> messages) {
this.message = message;
}
public List<String> getParticipants() {
return participants;
}
public void setParticipants(List<String> participants) {
this.participants = participants;
}
}
留言class如下;
public class Message {
private Long id;
private Session session;
private Date date;
private String participant;
private String content;
private List<Comment> comments;
public Message() {
}
public Message(String participant, Session session, Date date, String content) {
this.participant = participant;
this.session = session;
this.content = content;
this.date = date;
this.comments = new ArrayList<>();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getParticipant() {
return participant;
}
public void setParticipant(String participant) {
this.participant = participant;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
public void addComment(Comment comment) {
this.comments.add(comment);
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public TweetSession getSession() {
return session;
}
public void setSession(TweetSession session) {
this.session = session;
}
}
和评论 class;
public class Comment {
private Long id;
private Message message;
private String participant;
private String message;
private Date date;
public Comment() {
}
public Comment(String participant, Message message, String content, Date date) {
this.participant = participant;
this.content = content;
this.message = message;
this.date = date;
}
public String getParticipant() {
return participant;
}
public void setParticipant(String participant) {
this.participant = participant;
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
我想知道是否可以将其映射到 CSV 文件。当我将会话对象转换为 JSON 格式并在在线生成器中将 JSON 转换为 CSV 时,我得到了正确的输出,所以我认为这一定是可能的。我只是真的不知道该怎么做。 我试过像这样使用 net.sf.supercsv 库;
public void generateCSV(Session session, HttpServletResponse response) throws IOException {
String csvFileName = "session.csv";
response.setContentType("text/csv");
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"",
csvFileName);
response.setHeader(headerKey, headerValue);
ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(),
CsvPreference.STANDARD_PREFERENCE);
// Generate header for the CSV
Field fields[] = session.getClass().getDeclaredFields();
String[] header = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
header[i] = fields[i].getName();
}
csvWriter.writeHeader(header);
// Generate CSV content from data
csvWriter.write(session, header);
csvWriter.close();
}
但这当然不会得到想要的结果。
任何人都可以指出我正确的方向吗?
提前致谢,
尼尔斯
编辑:
这是 JSON 格式的示例会话:
{
"id": 22,
"startDate": 1447368081000,
"endDate": null,
"messages": [
{
"id": 10,
"date": 1447368159000,
"participant": "1",
"content": "This is a message",
"comments": []
},
{
"id": 11,
"date": 1447368168000,
"participant": "1",
"content": "This is also a message",
"comments": []
},
{
"id": 12,
"date": 1447368179000,
"participant": "1",
"content": "This is another message",
"comments": [
{
"id": 10,
"participant": "1",
"message": "This is a comment",
"date": 1447368227000
},
{
"id": 11,
"participant": "1",
"message": "This is also a comment",
"date": 1447368234000
}
]
}
],
"participants": [
"1",
"23"
]
}
当我将其转换为 CSV 时,我得到如下信息:
确实开始考虑(单个)CSV 可能不是解决此问题的最佳方法。
我们使用了 openCSV
com.opencsv.bean.BeanToCsv to achieve this
public void exportIronData(String destinationFilePath,
List<ExportIronDataFileFormatDTO> dataList) throws Exception {
try {
if (validationUtil.isNullOrEmpty(destinationFilePath)
|| validationUtil.isNullOrEmpty(dataList)) {
return;
}
ColumnPositionMappingStrategy<ExportIronDataFileFormatDTO> strategy = new ColumnPositionMappingStrategy<ExportIronDataFileFormatDTO>();
strategy.setType(ExportIronDataFileFormatDTO.class);
String[] columns = IlmcrCsvFileConstants.EXPORT_IRONDATA_COLUMN_HEADERS;
strategy.setColumnMapping(columns);
CSVWriter writer = new CSVWriter(
new FileWriter(destinationFilePath),
IlmcrCsvFileConstants.exportIronDataSeperator,
CSVWriter.NO_ESCAPE_CHARACTER, System.getProperty("line.separator"));
BeanToCsv<ExportIronDataFileFormatDTO> exportFormat = new BeanToCsv<ExportIronDataFileFormatDTO>();
exportFormat.write(strategy, writer, dataList);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
如果您还需要什么,请告诉我
我建议改用 Apache Commons CSV。我们已经在几个项目中使用它,包括管理我们的邮件列表。
Reader in = new StringReader("a,b,c");
for (CSVRecord record : CSVFormat.DEFAULT.parse(in)) {
for (String field : record) {
System.out.print("\"" + field + "\", ");
}
System.out.println();
}
Output: "a", "b", "c",
您拥有的数据有许多 1:n 依赖项,并不适合 单个 CSV 文件。
我已经使用或看到用于此的方法:
一个 "hybrid" CSV 包含
Session
自己的数据,即第一列中的id
、startDate
、endDate
和然后两列消息和参与者打印为 JSON"123", "2015-11-17", "2015-11-18", "[{id: 345, date: ...}, {id: 789, date: ...}]", "[...]"
(注意你需要使用一个很好的 CSV 库来转义包含
,
或"
s 的值)多个 CSV 文件 - 建模就像您为您的结构建模关系数据库,即
- sessions.csv 包含
id
、startDate
、endDate
- messages.csv 包含
id
、session_id
、date
、... - ...
然后将它们压缩为单个文件下载
- sessions.csv 包含
- 向您的用户询问更精确的规范 - 努力找出他们打算如何处理数据,然后以一种使他们能够轻松阅读的格式向他们提供 "view" 数据- 正是创建数据库视图和报告的方式为用户提供面向任务的数据视图。
您应该使用混合 CSV 格式。我遇到了同样的问题,所以我创建了一个轻量级框架。您可以从以下位置复制源代码或示例:https://github.com/abhisoni96/dev-tools
您可以为每个基于集合的数据成员创建自己的格式化程序。请参考上面的例子 link.
有一个库叫做 json2flat.
它所做的是获取一个复杂的 JSON 文档并将其转换为 CSV 格式。
所以您需要做的是将您的 java 对象转换为 JSON 格式。之后
您需要将生成的 JSON 传递到库中,它 returns 一个 2D
JSON 的表示,您还可以从中获取 csv。
这个库不是那么成熟,但仍然很有前途。
你应该试试看。