How to serialize object to CSV file?

前端 未结 8 1249
执念已碎
执念已碎 2020-11-27 17:14

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 ?

EDIT: I w

相关标签:
8条回答
  • 2020-11-27 17:53

    For easy CSV access, there is a library called OpenCSV. It really ease access to CSV file content.

    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 CsvJdbc driver, you can load your CSV files as JDBC data source, and then directly map your beans to this datasource.

    I would have talked to you about CSVObjects, but as the site seems broken, I fear the lib is unavailable nowadays.

    0 讨论(0)
  • 2020-11-27 17:57

    I wrote a simple class that uses OpenCSV and has two static public methods.

    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.

    0 讨论(0)
  • 2020-11-27 18:01

    You can use gererics to work for any class

    public class FileUtils<T> {
    public String createReport(String filePath, List<T> t) {
        if (t.isEmpty()) {
            return null;
        }
    
        List<String> reportData = new ArrayList<String>();
    
        addDataToReport(t.get(0), reportData, 0);
    
        for (T k : t) {
            addDataToReport(k, reportData, 1);
        }
        return !dumpReport(filePath, reportData) ? null : filePath;
    }
    
    public static Boolean dumpReport(String filePath, List<String> lines) {
        Boolean isFileCreated = false;
    
        
        String[] dirs = filePath.split(File.separator);
        String baseDir = "";
        for (int i = 0; i < dirs.length - 1; i++) {
            baseDir += " " + dirs[i];
        }
        baseDir = baseDir.replace(" ", "/");
        
        File base = new File(baseDir);
        base.mkdirs();
    
        File file = new File(filePath);
        try {
            if (!file.exists())
                file.createNewFile();
        } catch (Exception e) {
            e.printStackTrace();
            return isFileCreated;
        }
    
        try (BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(file), System.getProperty("file.encoding")))) {
            for (String line : lines) {
                writer.write(line + System.lineSeparator());
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    
    void addDataToReport(T t, List<String> reportData, int index) {
        String[] jsonObjectAsArray = new Gson().toJson(t).replace("{", "").replace("}", "").split(",\"");
        StringBuilder row = new StringBuilder();
    
        for (int i = 0; i < jsonObjectAsArray.length; i++) {
            String str = jsonObjectAsArray[i];
            str = str.replaceFirst(":", "_").split("_")[index];
    
            if (i == 0) {
                if (str != null) {
                    row.append(str.replace("\"", ""));
                } else {
                    row.append("N/A");
                }
            } else {
                if (str != null) {
                    row.append(", " + str.replace("\"", ""));
                } else {
                    row.append(", N/A");
                }
            }
        }
        reportData.add(row.toString());
    }
    
    0 讨论(0)
  • 2020-11-27 18:04

    Two options I just ran into:

    • http://sojo.sourceforge.net/
    • http://supercsv.sourceforge.net/
    0 讨论(0)
  • 2020-11-27 18:11

    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'

    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.

    Looks like Java CSV Library can do this, but I have not tried this myself.

    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):

    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.

    0 讨论(0)
  • 2020-11-27 18:14

    Worth mentioning that the handlebar library https://github.com/jknack/handlebars.java can trivialize many transformation tasks include toCSV.

    0 讨论(0)
提交回复
热议问题