I have a method that writes an object to a file for all fields, I need a method that writes only selected fields to a file
public void makeSCV(List<String> fields){
String name = "";
String FILE_NAME= "C:\\Users\\Admin\\Documents\\files.csv";
try {
PrintWriter pw= new PrintWriter(new File(FILE_NAME));
StringBuilder sb=new StringBuilder();
List<Customer> list = customerRepository.findAll();
for(Customer obj : list){
name = obj.getFullName() "," obj.getId() "," obj.getEmail()
"," obj.getPhone() "," obj.getCreated() "," obj.getUpdated() "\r\n";
sb.append(name);
}
pw.write(sb.toString());
pw.close();
} catch (Exception e) {
// TODO: handle exception
}
}
CodePudding user response:
You can use Reflection for this. This way, there is no hard-coded behavior, so you can add fields and change the order at any time without changing the code, even at runtime!
public static void makeSCV(List<String> fields, List<Customer> customers) throws IOException {
// Get desired fields via reflection
var outPutFields = Arrays.stream(Customer.class.getDeclaredFields())
.filter(o1 -> fields.contains(o1.getName())) // Only specified fields
.sorted(Comparator.comparingInt(o -> fields.indexOf(o.getName()))) // Order like specified
.peek(field -> field.setAccessible(true)) // For private fields
.collect(Collectors.toList());
var csvString = customers.stream()
.map(customer -> outPutFields.stream()
.map(field -> {
try {
return field.get(customer).toString(); // get value of field for given object
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList())
.toArray(new String[]{})
)
.map(objects -> String.join(",", objects)) // single csv line
.collect(Collectors.joining("\r\n")); /// join csv lines
// Write to file
Files.write(Path.of("/path/to/outputFile.csv"), csvString.getBytes(StandardCharsets.UTF_8));
}
CodePudding user response:
You can make it more generic by adding diff methods in the Customer model.
i.e
class Customer {
//properties
public String getCustomerDetails(String type) {
switch(type) {
case "ONE":
return obj.getFullName();
case "TWO":
return obj.getFullName() "," obj.getId();
case "THREE":
return obj.getFullName() "," obj.getId() "," obj.getEmail();
...
default:
...
}
}
Then you can update your method and pass the type as an argument.
i.e
public void makeSCV(List<String> fields, String type){
String name = "";
String FILE_NAME= "C:\\Users\\Admin\\Documents\\files.csv";
try {
PrintWriter pw= new PrintWriter(new File(FILE_NAME));
StringBuilder sb=new StringBuilder();
List<Customer> list = customerRepository.findAll();
for(Customer obj : list){
sb.append(obj.getCustomerDetails(type));
}
pw.write(sb.toString());
pw.close();
} catch (Exception e) {
// TODO: handle exception
}
}