Java 将Bean/ResultSet写入CSV文件的已知API

Java 将Bean/ResultSet写入CSV文件的已知API,java,api,csv,Java,Api,Csv,我想通过反射机制将JavaBean或ResultSet(JDBC)导出到CSV文件中 我看过这个api: 但它还没有发布 此外,如果我们可以设置一些过滤器,以避免映射某些精确的字段,也可以 您知道拥有这些功能的已知API吗?除非有一些现成的API:s我会使用 apachecommons获取JavaBean的字符串表示。通过设置自己的ToStringStyle可以创建CSV样式的字符串。有许多可能的字符串样式设置,包括排除字段等。 然后当然把它写进一个文件 除非有现成的API:s我会使用 apa

我想通过反射机制将JavaBean或ResultSet(JDBC)导出到CSV文件中

我看过这个api:

但它还没有发布

此外,如果我们可以设置一些过滤器,以避免映射某些精确的字段,也可以


您知道拥有这些功能的已知API吗?

除非有一些现成的API:s我会使用 apachecommons获取JavaBean的字符串表示。通过设置自己的
ToStringStyle
可以创建CSV样式的字符串。有许多可能的字符串样式设置,包括排除字段等。
然后当然把它写进一个文件

除非有现成的API:s我会使用 apachecommons获取JavaBean的字符串表示。通过设置自己的
ToStringStyle
可以创建CSV样式的字符串。有许多可能的字符串样式设置,包括排除字段等。
然后当然把它写进一个文件

您可以使用outputstream或其他类似工具,像写入普通.txt文件一样写入csv文件。
如果您需要更高级的类似excel的东西,我建议您使用ApachePOI。对我来说,它总是做得很好,很干净。

你可以像写普通的.txt文件一样,通过使用outputstream之类的文件写入csv文件。
如果您需要更高级的类似excel的东西,我建议您使用ApachePOI。它一直为我做得很好,很干净。

添加到犬舍答案:

我实现了两个类:一个用于标题(如果需要),另一个用于正文(实际数据)

标题

  • header样式类需要扩展到String样式
  • 使用单个元素调用toString,例如ReflectionStringBuilder.toString(第一个元素,headerStyle)
建造商:

this.setUseClassName(false);
this.setUseIdentityHashCode(false);
this.setContentStart("");
this.setUseFieldNames(true);
this.setFieldNameValueSeparator("");
this.setContentEnd("\n");
this.setUseClassName(false);
this.setUseIdentityHashCode(false);
this.setContentStart("");
this.setUseFieldNames(false);
this.setContentEnd("");
this.setNullText("n.a.");
this.setArrayStart("");
this.setArrayEnd("");
this.setArraySeparator("\n");
覆盖方法:

@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
    super.append(buffer, fieldName, "", fullDetail);
}
@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {

    String csvField = Optional.ofNullable(value)
            .map(Objects::toString)
            .map(this::escapeLineBreak)
            .map(this::escapeDoubleQuote)
            .map(this::escapeField)
            .orElse(null);

    super.append(buffer, fieldName, csvField, fullDetail);
}
身体

  • body类需要扩展RecursiveToString样式
  • 使用数组调用toString,例如ReflectionStringBuilder.toString(数组,bodyStyle)
建造商:

this.setUseClassName(false);
this.setUseIdentityHashCode(false);
this.setContentStart("");
this.setUseFieldNames(true);
this.setFieldNameValueSeparator("");
this.setContentEnd("\n");
this.setUseClassName(false);
this.setUseIdentityHashCode(false);
this.setContentStart("");
this.setUseFieldNames(false);
this.setContentEnd("");
this.setNullText("n.a.");
this.setArrayStart("");
this.setArrayEnd("");
this.setArraySeparator("\n");
覆盖方法:

@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
    super.append(buffer, fieldName, "", fullDetail);
}
@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {

    String csvField = Optional.ofNullable(value)
            .map(Objects::toString)
            .map(this::escapeLineBreak)
            .map(this::escapeDoubleQuote)
            .map(this::escapeField)
            .orElse(null);

    super.append(buffer, fieldName, csvField, fullDetail);
}
格式化方法:

private String escapeDoubleQuote(final String field) {
    return field.replace("\"", "\"\"");
}

private String escapeLineBreak(final String field) {
    return field.replaceAll("\\R", " ");
}

private String escapeField(final String field) {
    return "\"" + field + "\"";
}

补充犬舍的答案:

我实现了两个类:一个用于标题(如果需要),另一个用于正文(实际数据)

标题

  • header样式类需要扩展到String样式
  • 使用单个元素调用toString,例如ReflectionStringBuilder.toString(第一个元素,headerStyle)
建造商:

this.setUseClassName(false);
this.setUseIdentityHashCode(false);
this.setContentStart("");
this.setUseFieldNames(true);
this.setFieldNameValueSeparator("");
this.setContentEnd("\n");
this.setUseClassName(false);
this.setUseIdentityHashCode(false);
this.setContentStart("");
this.setUseFieldNames(false);
this.setContentEnd("");
this.setNullText("n.a.");
this.setArrayStart("");
this.setArrayEnd("");
this.setArraySeparator("\n");
覆盖方法:

@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
    super.append(buffer, fieldName, "", fullDetail);
}
@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {

    String csvField = Optional.ofNullable(value)
            .map(Objects::toString)
            .map(this::escapeLineBreak)
            .map(this::escapeDoubleQuote)
            .map(this::escapeField)
            .orElse(null);

    super.append(buffer, fieldName, csvField, fullDetail);
}
身体

  • body类需要扩展RecursiveToString样式
  • 使用数组调用toString,例如ReflectionStringBuilder.toString(数组,bodyStyle)
建造商:

this.setUseClassName(false);
this.setUseIdentityHashCode(false);
this.setContentStart("");
this.setUseFieldNames(true);
this.setFieldNameValueSeparator("");
this.setContentEnd("\n");
this.setUseClassName(false);
this.setUseIdentityHashCode(false);
this.setContentStart("");
this.setUseFieldNames(false);
this.setContentEnd("");
this.setNullText("n.a.");
this.setArrayStart("");
this.setArrayEnd("");
this.setArraySeparator("\n");
覆盖方法:

@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
    super.append(buffer, fieldName, "", fullDetail);
}
@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {

    String csvField = Optional.ofNullable(value)
            .map(Objects::toString)
            .map(this::escapeLineBreak)
            .map(this::escapeDoubleQuote)
            .map(this::escapeField)
            .orElse(null);

    super.append(buffer, fieldName, csvField, fullDetail);
}
格式化方法:

private String escapeDoubleQuote(final String field) {
    return field.replace("\"", "\"\"");
}

private String escapeLineBreak(final String field) {
    return field.replaceAll("\\R", " ");
}

private String escapeField(final String field) {
    return "\"" + field + "\"";
}