How can Object[] represent CSV data? Does it contain one row with several columns or several rows with one column? I would suggest that Object[][] or List<List<Object>> makes more sense.
In any case, you must adhere to the RFC4180 specification when creating the CSV file. It is basically simple, there are only 3 strict rules:
- Fields are separated by a comma.
- If the comma occurs inside the field, then the field must be surrounded by double quotation marks.
- If a double quotation mark occurs inside a field, then the field must be surrounded by double quotation marks, and the double quotation mark inside the field must be escaped by another double quotation mark.
Here's a run example that does just that, based on List<List<T>> as the source and OutputStream as the destination.
public static <T> void writeCsv (List<List<T>> csv, char separator, OutputStream output) throws IOException { BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8")); for (List<T> row : csv) { for (Iterator<T> iter = row.iterator(); iter.hasNext();) { String field = String.valueOf(iter.next()).replace("\"", "\"\""); if (field.indexOf(separator) > -1 || field.indexOf('"') > -1) { field = '"' + field + '"'; } writer.append(field); if (iter.hasNext()) { writer.append(separator); } } writer.newLine(); } writer.flush(); }
Here you can use it in the servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<List<Object>> csv = getItSomehow(); response.setHeader("Content-Type", "text/csv"); response.setHeader("Content-Disposition", "attachment;filename=\"file.csv\""); writeCsv(csv, ';', response.getOutputStream()); }
(note that in European locations instead of a semicolon for CSV files, a semicolon is used instead of a semicolon, do not hesitate to change)
Content-Disposition of attachment forces the Save As dialog. Note that MSIE has an incorrect behavior that does not accept filename as the default file name in the Save As dialog box, but instead occupies the last part of pathinfo. Therefore, if this servlet, for example, is called http://example.com/csv , you will get csv as the default file name. Rather, add it to pathinfo, as http://example.com/csv/file.csv follows. The servlet should only display on url-pattern /csv/* instead of /csv .
Balusc
source share