我有多个csv文件包含大约200到300列,我需要创建pojos与他们之间的映射一对一(列太Java类字段)。不要介意不推荐的事实。 如果您知道一个工具或如何自动执行此操作,请参阅。如何从csv文件生成java类
因此,您有一个csv文件,其中包含数百行包含数百个列的行,第一行包含列标题。所以我需要基于第一行(列标题)创建一个包含这些标题作为类字段的java类。没关系实际的数据。我只需要一个与这些领域的Java类
有一个关于这个帖子有些问题,但这是3年前问,所以我猜是过时了。
我有多个csv文件包含大约200到300列,我需要创建pojos与他们之间的映射一对一(列太Java类字段)。不要介意不推荐的事实。 如果您知道一个工具或如何自动执行此操作,请参阅。如何从csv文件生成java类
因此,您有一个csv文件,其中包含数百行包含数百个列的行,第一行包含列标题。所以我需要基于第一行(列标题)创建一个包含这些标题作为类字段的java类。没关系实际的数据。我只需要一个与这些领域的Java类
有一个关于这个帖子有些问题,但这是3年前问,所以我猜是过时了。
可以使用了Javassist在运行时生成类:
代码:
public static void main(String[] args) throws Exception {
String[] fieldNames = null;
Class<?> rowObjectClass = null;
try(BufferedReader stream = new BufferedReader(new InputStreamReader(Program.class.getResourceAsStream("file.csv")))) {
while(true) {
String line = stream.readLine();
if(line == null) {
break;
}
if(line.isEmpty() || line.startsWith("#")) {
continue;
}
if(rowObjectClass == null) {
fieldNames = line.split(",");
rowObjectClass = buildCSVClass(fieldNames);
} else {
String[] values = line.split(",");
Object rowObject = rowObjectClass.newInstance();
for (int i = 0; i < fieldNames.length; i++) {
Field f = rowObjectClass.getDeclaredField(fieldNames[i]);
f.setAccessible(true);
f.set(rowObject, values[i]);
}
System.out.println(reflectToString(rowObject));
}
}
}
}
private static int counter = 0;
public static Class<?> buildCSVClass(String[] fieldNames) throws CannotCompileException, NotFoundException {
ClassPool pool = ClassPool.getDefault();
CtClass result = pool.makeClass("CSV_CLASS$" + (counter++));
ClassFile classFile = result.getClassFile();
ConstPool constPool = classFile.getConstPool();
classFile.setSuperclass(Object.class.getName());
for (String fieldName : fieldNames) {
CtField field = new CtField(ClassPool.getDefault().get(String.class.getName()), fieldName, result);
result.addField(field);
}
classFile.setVersionToJava5();
return result.toClass();
}
public static String reflectToString(Object value) throws IllegalAccessException {
StringBuilder result = new StringBuilder(value.getClass().getName());
result.append("@").append(System.identityHashCode(value)).append(" {");
for (Field f : value.getClass().getDeclaredFields()) {
f.setAccessible(true);
result.append("\n\t").append(f.getName()).append(" = ").append(f.get(value)).append(", ");
}
result.delete(result.length()-2, result.length());
return result.append("\n}").toString();
}
资源:
FILE.CSV(类路径):
############
foo,bar
############
hello,world
cafe,babe
输出:
[email protected] {
foo = hello,
bar = world
}
[email protected] {
foo = cafe,
bar = babe
}
按我undersatnding,你想读的大范围列的csv文件,而把它当作一个表数据库
我的解决方案如下
这可以通过使用文件作为数据源和csvjdbc驱动器,并使用元数据来完成,你可以检索所有列
这是可以做到和refernce是 here
该版本不使用任何花哨的类生成代码;相反,它输出Java源文件(或者更准确地说,是一个单独的类文件,CSV中每个非标题行都有一个静态公共内部子类)。
对于以下输入(来自Binkan借用):
############
foo,bar
############
he"l\nl"o,world
cafe,babe
输出将是:
public class Out {
public static class Row1 {
public String foo = "he\"l\\nl\"o";
public String bar = "world";
}
public static class Row2 {
public String foo = "cafe";
public String bar = "babe";
}
}
这里是代码;从Binkan的部分改编至于行由行阅读:
public class T {
public static void classesFromRows(String fileName, PrintWriter out, String classNamePrefix) throws Exception{
try(BufferedReader stream = new BufferedReader(new FileReader(fileName))) {
String line = null;
String[] fields = null;
int rowNum = 0;
while ((line = stream.readLine()) != null) {
if (line.isEmpty() || line.startsWith("#")) {
// do nothing
} else if (fields == null) {
fields = line.split(",");
} else {
rowNum ++;
String[] values = line.split(",");
out.println("\tpublic static class " + classNamePrefix + rowNum + " {");
for (int i=0; i<fields.length; i++) {
out.println("\t\tpublic String " + fields[i] + " = \""
+ StringEscapeUtils.escapeJava(values[i]) + "\";");
}
out.println("\t}");
}
}
}
}
// args[0] = input csv; args[1] = output file
public static void main(String[] args) throws Exception {
File outputFile = new File(args[1]);
String outputClass = outputFile.getName().replace(".java", "");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(outputFile)));
// missing: add a package here, if you want one
out.println("public class " + outputClass + " {");
classesFromRows(args[0], out, "Row");
out.println("}");
out.close();
}
}
我选择要考虑所有的数据字符串(光明的一面,我使用StringEscapeUtils正确逃脱他们);有了更多的代码,你可以指定其他类型。
我不认为它打算把所有的行放在单独的类中,而不是用第一行中描述的字段来放置所有的行 –
这是可能的;而且我的代码很容易修复来处理它。尽管如此,我认为上述代码或修订版本对任何人都不会有多大用处,除了证明编写原始源代码生成器是多么容易。 – tucuxi
您可以使用Javassist在运行时生成类 –
您可以提供一个映射/ csv文件的一对一示例吗? –
一个csv列应该生成一个类字段,所以255个csv列应该给我一个包含255个字段的类:) – aurelius