Reputation: 404
I would have the need to produce a CSV File with the following requirements:
Input:
Expected output:
"Field1"|"Field2With\\Backslash\"DoubleQuotes\"And|Pipe"|"Field3"
Is it possible to obtain such an output?
Upvotes: 0
Views: 935
Reputation: 404
The best solution is to implement quoting and escaping in a subclass of ExtractorLineAggregator.
public final class CustomDelimitedLineAggregator<T> extends ExtractorLineAggregator<T> {
private String delimiterChar = ",";
private String quoteChar = "\"";
private String escapeChar = "\\";
public CustomDelimitedLineAggregator() {
}
public CustomDelimitedLineAggregator(String delimiterChar){
this.delimiterChar = delimiterChar;
}
// getters and setters..
@Override
public String doAggregate(Object[] fieldList) {
if (isEmpty(fieldList)) {
return quote("");
}
if (fieldList.length == 1) {
return quote(escape((valueOf(fieldList[0]))));
}
String aggregated = "";
for (int i = 0; i < fieldList.length; i++) {
if (i > 0) {
aggregated += delimiterChar;
}
String field = valueOf(fieldList[i]);
aggregated+=(quote(escape(field)));
}
return aggregated;
}
public String doAggregate(List<String> fieldList) {
if (isEmpty(fieldList)) {
return doAggregate((Object[]) null);
}
return doAggregate(fieldList.toArray(new Object[0]));
}
private String escape(String s) {
if (s == null) {
return null;
}
return s.replace(escapeChar, escapeChar + escapeChar)
.replace(quoteChar, escapeChar + quoteChar);
}
private String quote(String s) {
if (s == null) {
return quoteChar + quoteChar;
}
return quoteChar + s + quoteChar;
}
}
Upvotes: 0
Reputation: 195
Basically, you just want to process your fields before writing it. You could do it with these 2 ways
Let's say this method processes your field
public String escape(String str) {
str = "\"" + str + "\"";
str = str.replace("|", "\\|");
str = str.replace("\\", "\\\\");
return str;
}
1 - Process it during processor - preferred
@Override
public A process(B b) throws Exception {
A a = new A();
//Process b to a...
a.setField1(escape(a.getField1)); //For each fields
return a;
}
2 - Process it before writing in custom Writer
public class EscapeFlatFileItemWriter<A> extends FlatFileItemWriter<A> {
@Override
public void write(List<? extends A> items) throws Exception {
for (A a : items) {
a.setField1(escape(a.getField1)); //For each fields
}
super.write(items);
}
}
Upvotes: 0