Writing generic POJO to CSV transformer

dushyantashu picture dushyantashu · Jan 6, 2017 · Viewed 11.6k times · Source

My use case was to write a generic CSV transformer, which should be able to convert any Java POJO to CSV string.

My Implementation :

public <T> List<String> convertToString(List<T> objectList) {

        List<String> stringList = new ArrayList<>();
        char delimiter = ',';
        char quote = '"';
        String lineSep = "\n";

        CsvMapper mapper = new CsvMapper();
        CsvSchema schema = mapper.schemaFor(!HOW_TO!);

        for (T object : objectList) {

            try {
                String csv = mapper.writer(schema
                        .withColumnSeparator(delimiter)
                        .withQuoteChar(quote)
                        .withLineSeparator(lineSep)).writeValueAsString(object);

            } catch (JsonProcessingException e) {

                System.out.println(e);
            }
        }

        return stringList;
}

I was using Jackson-dataformat-csv library, but I'm stuck with !HOW_TO! part, ie How to extract the .class of the object from the objectList. I was studying and came across Type Erasure, So I think it is somehow not possible other than giving the .class as parameter to my function. But I'm also extracting this object list from generic entity using Java Reflection, so I can't have the option to provide the .class params.

Is there a workaround for this?

OR

Any other approaches/libraries where I can convert a generic List<T> objectList to List<String> csvList with functionality of adding delimiters, quote characters, line separators etc.

Thanks!

Answer

Devendra Dora picture Devendra Dora · Apr 17, 2018

I have created a CSVUtil Class similar to below which uses java reflection.

Example to use below CSVUtil Assuming POJO Student ,

List<Student> StudentList = new ArrayList<Student>();
String StudentCSV = CSVUtil.toCSV(StudentList,' ',false);


import java.lang.reflect.Field;
import java.util.List;
import java.util.logging.Logger;

CSVUtil class

public class CSVUtil {
    private static final Logger LOGGER = Logger.getLogger(CSVUtil.class .getName());
    private final static char DEFAULT_SEPARATOR = ' ';

    public static String toCSV(List<?> objectList, char separator, boolean displayHeader) {
        
        StringBuilder result =new StringBuilder();  
        if (objectList.size() == 0) {
            return result.toString();
        }   
       
        if(displayHeader){
            result.append(getHeaders(objectList.get(0),separator)); 
            result.append("\n");
        }
        
        for (Object obj : objectList) {
            result.append(addObjectRow(obj, separator)).append("\n");
        }
        
        return result.toString();
    }
    
    public static String getHeaders(Object obj,char separator) {
        StringBuilder resultHeader = new StringBuilder(); 
        boolean firstField = true;
        Field fields[] = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String value;
            try {
                value = field.getName();
                
                if(firstField){
                     resultHeader.append(value);
                     firstField = false;
                 }
                 else{
                    resultHeader.append(separator).append(value);
                 }
                field.setAccessible(false);
            } catch (IllegalArgumentException  e) {
                LOGGER.severe(e.toString());
            }
        }           
      return resultHeader.toString();
        
    }
    

    public static String addObjectRow(Object obj, char separator) {
        
        StringBuilder csvRow =new StringBuilder();  
        Field fields[] = obj.getClass().getDeclaredFields();
        boolean firstField = true;
        for (Field field : fields) {
            field.setAccessible(true);
            Object value;
            try {
                value = field.get(obj);
                if(value == null)
                    value = "";
                if(firstField){
                    csvRow.append(value);
                    firstField = false;
                }
                else{
                    csvRow.append(separator).append(value);
                }
                field.setAccessible(false);
            } catch (IllegalArgumentException | IllegalAccessException e) {
                LOGGER.severe(e.toString());
            }
        }
        return csvRow.toString();
    }
}