Csv.java
package com.rbctcsworld.ecommerce.common;
import java.util.List;
/** CSV that opens safely in a spreadsheet: every text cell quoted, formulas defused (OWASP CSV injection). */
public final class Csv {
private Csv() {
}
/**
* One text cell: quoted, inner quotes doubled. A value a spreadsheet would run as a formula
* (=, +, -, @, tab, carriage return at the start) gets a leading apostrophe. null = empty cell.
*/
public static String cell(String value) {
if (value == null) return "";
String v = value;
if (!v.isEmpty() && "=+-@\t\r".indexOf(v.charAt(0)) >= 0) v = "'" + v;
return "\"" + v.replace("\"", "\"\"") + "\"";
}
/** Numbers as they are (so the spreadsheet can add them up), everything else as a text cell. */
public static String value(Object v) {
if (v == null) return "";
if (v instanceof Number n) return n instanceof java.math.BigDecimal d ? d.toPlainString() : n.toString();
return cell(v.toString());
}
/** One line, CRLF-terminated (RFC 4180). */
public static String line(List<?> values) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < values.size(); i++) {
if (i > 0) s.append(',');
s.append(value(values.get(i)));
}
return s.append("\r\n").toString();
}
}