如何从csv文件生成java类

我有多个包含大约200到300列的csv文件,我需要使用一对一的映射创建pojos(列也是java类字段)。 别担心不推荐的事实。 如果您知道某个工具或如何自动执行此操作,请投入。

所以你有一个csv文件,包含数千个包含数百列的行,第一行包含列的标题。 所以我需要的是,基于第一行(列的标题)来创建一个包含这些标题作为类字段的java类。 别介意实际数据。 我只需要一个包含这些字段的java类

关于这个post有一个问题,但大约在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(classpath):

 ############ foo,bar ############ hello,world cafe,babe 

输出:

 CSV_CLASS$0@1324706137 { foo = hello, bar = world } CSV_CLASS$0@1373076110 { foo = cafe, bar = babe } 

根据我的不足,您正在尝试读取包含大量列的csv文件,将其视为数据库表

我的解决方案如下

  • 使用csvjdbc查询数据列

这可以通过使用文件作为数据源和csvjdbc驱动程序来完成,并使用元数据,您可以检索所有列

  • 使用工具Provider创建运行时POJO类

这可以完成,参考就在这里

此版本不使用任何花哨的类生成代码; 相反,它输出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 

我选择将所有数据都视为字符串(从好的方面来说,我正在使用StringEscapeUtils正确地转义它们); 使用更多代码,您可以指定其他类型。