Java 如何将对象序列化为 CSV 文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3666007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to serialize object to CSV file?
提问by
I want to write a Object into CSV file.
For XML we have XStream like this
So if i want to convert object to CSV do we have any such library ?
我想将一个对象写入 CSV 文件。对于XML,我们有XStream的像这样
所以,如果我想转换对象CSV我们是否有任何这样的图书馆吗?
EDIT: I want to pass my list of Bean to a method which should write all the fields of bean to CSV.
编辑: 我想将我的 Bean 列表传递给一个方法,该方法应该将 bean 的所有字段写入 CSV。
采纳答案by Nivas
First, serialization is writing the object to a file 'as it is'. AFAIK, you cannot choose file formats and all. The serialized object (in a file) has its own 'file format'
首先,序列化是将对象“按原样”写入文件。AFAIK,您不能选择文件格式等等。序列化对象(在文件中)有自己的“文件格式”
If you want to write the contents of an object (or a list of objects) to a CSV file, you can do it yourself, it should not be complex.
如果你想把一个对象(或者一个对象列表)的内容写入一个CSV文件,你可以自己做,应该不会很复杂。
Looks like Java CSV Librarycan do this, but I have not tried this myself.
看起来Java CSV 库可以做到这一点,但我自己没有尝试过。
EDIT: See following sample. This is by no way foolproof, but you can build on this.
编辑:请参阅以下示例。这绝不是万无一失的,但您可以以此为基础。
//European countries use ";" as
//CSV separator because "," is their digit separator
private static final String CSV_SEPARATOR = ",";
private static void writeToCSV(ArrayList<Product> productList)
{
try
{
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("products.csv"), "UTF-8"));
for (Product product : productList)
{
StringBuffer oneLine = new StringBuffer();
oneLine.append(product.getId() <=0 ? "" : product.getId());
oneLine.append(CSV_SEPARATOR);
oneLine.append(product.getName().trim().length() == 0? "" : product.getName());
oneLine.append(CSV_SEPARATOR);
oneLine.append(product.getCostPrice() < 0 ? "" : product.getCostPrice());
oneLine.append(CSV_SEPARATOR);
oneLine.append(product.isVatApplicable() ? "Yes" : "No");
bw.write(oneLine.toString());
bw.newLine();
}
bw.flush();
bw.close();
}
catch (UnsupportedEncodingException e) {}
catch (FileNotFoundException e){}
catch (IOException e){}
}
This is product (getters and setters hidden for readability):
这是产品(为了可读性隐藏了 getter 和 setter):
class Product
{
private long id;
private String name;
private double costPrice;
private boolean vatApplicable;
}
And this is how I tested:
这就是我测试的方式:
public static void main(String[] args)
{
ArrayList<Product> productList = new ArrayList<Product>();
productList.add(new Product(1, "Pen", 2.00, false));
productList.add(new Product(2, "TV", 300, true));
productList.add(new Product(3, "iPhone", 500, true));
writeToCSV(productList);
}
Hope this helps.
希望这可以帮助。
Cheers.
干杯。
回答by Riduidel
For easy CSV access, there is a library called OpenCSV. It really ease access to CSV file content.
为了方便 CSV 访问,有一个名为OpenCSV的库。它确实可以轻松访问 CSV 文件内容。
EDIT
编辑
According to your update, I consider all previous replies as incorrect (due to their low-levelness). You can then go a completely diffferent way, the hibernate way, in fact !
根据您的更新,我认为以前的所有回复都是不正确的(由于它们的级别低)。然后,您可以采用完全不同的方式,实际上是休眠方式!
By using the CsvJdbcdriver, you can load your CSV files as JDBC data source, and then directly map your beans to this datasource.
通过使用CsvJdbc驱动程序,您可以加载您的 CSV 文件作为 JDBC 数据源,然后将您的 bean 直接映射到此数据源。
I would have talked to you about CSVObjects, but as the site seems broken, I fear the lib is unavailable nowadays.
我会和你谈论CSVObjects,但由于该站点似乎已损坏,我担心现在该库不可用。
回答by user1057653
It would be interesting to have a csv serializer as it would take up the minimal space compared to other serializing method.
有一个 csv 序列化器会很有趣,因为与其他序列化方法相比,它占用的空间最小。
The closest support for java object to csv is stringutils provided by spring utils project
对java对象最接近csv的支持是spring utils项目提供的stringutils
arrayToCommaDelimitedString(Object[] arr) but it is far from being a serializer.
arrayToCommaDelimitedString(Object[] arr) 但它远不是序列化程序。
Here is a simple utility which uses reflection to serialize value objects
这是一个简单的实用程序,它使用反射来序列化值对象
public class CSVWriter
{
private static String produceCsvData(Object[] data) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
if(data.length==0)
{
return "";
}
Class classType = data[0].getClass();
StringBuilder builder = new StringBuilder();
Method[] methods = classType.getDeclaredMethods();
for(Method m : methods)
{
if(m.getParameterTypes().length==0)
{
if(m.getName().startsWith("get"))
{
builder.append(m.getName().substring(3)).append(',');
}
else if(m.getName().startsWith("is"))
{
builder.append(m.getName().substring(2)).append(',');
}
}
}
builder.deleteCharAt(builder.length()-1);
builder.append('\n');
for(Object d : data)
{
for(Method m : methods)
{
if(m.getParameterTypes().length==0)
{
if(m.getName().startsWith("get") || m.getName().startsWith("is"))
{
System.out.println(m.invoke(d).toString());
builder.append(m.invoke(d).toString()).append(',');
}
}
}
builder.append('\n');
}
builder.deleteCharAt(builder.length()-1);
return builder.toString();
}
public static boolean generateCSV(File csvFileName,Object[] data)
{
FileWriter fw = null;
try
{
fw = new FileWriter(csvFileName);
if(!csvFileName.exists())
csvFileName.createNewFile();
fw.write(produceCsvData(data));
fw.flush();
}
catch(Exception e)
{
System.out.println("Error while generating csv from data. Error message : " + e.getMessage());
e.printStackTrace();
return false;
}
finally
{
if(fw!=null)
{
try
{
fw.close();
}
catch(Exception e)
{
}
fw=null;
}
}
return true;
}
}
}
Here is an example value object
这是一个示例值对象
public class Product {
private String name;
private double price;
private int identifier;
private boolean isVatApplicable;
public Product(String name, double price, int identifier,
boolean isVatApplicable) {
super();
this.name = name;
this.price = price;
this.identifier = identifier;
this.isVatApplicable = isVatApplicable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(long price) {
this.price = price;
}
public int getIdentifier() {
return identifier;
}
public void setIdentifier(int identifier) {
this.identifier = identifier;
}
public boolean isVatApplicable() {
return isVatApplicable;
}
public void setVatApplicable(boolean isVatApplicable) {
this.isVatApplicable = isVatApplicable;
}
}
}
and the code to run the util
以及运行 util 的代码
public class TestCSV
{
public static void main(String... a)
{
Product[] list = new Product[5];
list[0] = new Product("dvd", 24.99, 967, true);
list[1] = new Product("pen", 4.99, 162, false);
list[2] = new Product("ipad", 624.99, 234, true);
list[3] = new Product("crayons", 4.99,127, false);
list[4] = new Product("laptop", 1444.99, 997, true);
CSVWriter.generateCSV(new File("C:\products.csv"),list);
}
}
Output:
输出:
Name VatApplicable Price Identifier
dvd true 24.99 967
pen false 4.99 162
ipad true 624.99 234
crayons false 4.99 127
laptop true 1444.99 997
回答by mmasters
Two options I just ran into:
我刚刚遇到的两个选项:
回答by ArtOfWarfare
I wrote a simple class that uses OpenCSV
and has two static public
methods.
我写了一个简单的类,它使用OpenCSV
并有两种static public
方法。
static public File toCSVFile(Object object, String path, String name) {
File pathFile = new File(path);
pathFile.mkdirs();
File returnFile = new File(path + name);
try {
CSVWriter writer = new CSVWriter(new FileWriter(returnFile));
writer.writeNext(new String[]{"Member Name in Code", "Stored Value", "Type of Value"});
for (Field field : object.getClass().getDeclaredFields()) {
writer.writeNext(new String[]{field.getName(), field.get(object).toString(), field.getType().getName()});
}
writer.flush();
writer.close();
return returnFile;
} catch (IOException e) {
Log.e("EasyStorage", "Easy Storage toCSVFile failed.", e);
return null;
} catch (IllegalAccessException e) {
Log.e("EasyStorage", "Easy Storage toCSVFile failed.", e);
return null;
}
}
static public void fromCSVFile(Object object, File file) {
try {
CSVReader reader = new CSVReader(new FileReader(file));
String[] nextLine = reader.readNext(); // Ignore the first line.
while ((nextLine = reader.readNext()) != null) {
if (nextLine.length >= 2) {
try {
Field field = object.getClass().getDeclaredField(nextLine[0]);
Class<?> rClass = field.getType();
if (rClass == String.class) {
field.set(object, nextLine[1]);
} else if (rClass == int.class) {
field.set(object, Integer.parseInt(nextLine[1]));
} else if (rClass == boolean.class) {
field.set(object, Boolean.parseBoolean(nextLine[1]));
} else if (rClass == float.class) {
field.set(object, Float.parseFloat(nextLine[1]));
} else if (rClass == long.class) {
field.set(object, Long.parseLong(nextLine[1]));
} else if (rClass == short.class) {
field.set(object, Short.parseShort(nextLine[1]));
} else if (rClass == double.class) {
field.set(object, Double.parseDouble(nextLine[1]));
} else if (rClass == byte.class) {
field.set(object, Byte.parseByte(nextLine[1]));
} else if (rClass == char.class) {
field.set(object, nextLine[1].charAt(0));
} else {
Log.e("EasyStorage", "Easy Storage doesn't yet support extracting " + rClass.getSimpleName() + " from CSV files.");
}
} catch (NoSuchFieldException e) {
Log.e("EasyStorage", "Easy Storage fromCSVFile failed.", e);
} catch (IllegalAccessException e) {
Log.e("EasyStorage", "Easy Storage fromCSVFile failed.", e);
}
} // Close if (nextLine.length >= 2)
} // Close while ((nextLine = reader.readNext()) != null)
} catch (FileNotFoundException e) {
Log.e("EasyStorage", "Easy Storage fromCSVFile failed.", e);
} catch (IOException e) {
Log.e("EasyStorage", "Easy Storage fromCSVFile failed.", e);
} catch (IllegalArgumentException e) {
Log.e("EasyStorage", "Easy Storage fromCSVFile failed.", e);
}
}
I think with some simple recursion these methods could be modified to handle any Java object, but for me this was adequate.
我认为通过一些简单的递归可以修改这些方法来处理任何 Java 对象,但对我来说这已经足够了。
回答by Abhishek Soni
Though its very late reply, I have faced this problem of exporting java entites to CSV, EXCEL etc in various projects, Where we need to provide export feature on UI.
尽管回复很晚,但我在各种项目中遇到了将 java entites 导出为 CSV、EXCEL 等的问题,我们需要在 UI 上提供导出功能。
I have created my own light weight framework. It works with any Java Beans, You just need to add annotations on fields you want to export to CSV, Excel etc.
我已经创建了自己的轻量级框架。它适用于任何 Java Bean,您只需要在要导出到 CSV、Excel 等的字段上添加注释。
回答by aggaton
Worth mentioning that the handlebar library https://github.com/jknack/handlebars.javacan trivialize many transformation tasks include toCSV.
值得一提的是,车把库https://github.com/jknack/handlebars.java可以简化许多转换任务,包括 toCSV。