Как может Object[]
представлять CSV-данные? Он содержит одну строку с несколькими столбцами или несколькими строками с одним столбцом? Я бы предположил, что Object[][]
или List<List<Object>>
имеет больше смысла.
В любом случае, при создании файла CSV вы должны придерживаться RFC4180 spec. Это в основном просто, существует только 3 строгих правила:
- Поля разделяются запятой.
- Если запятая встречается внутри поля, то поле должно быть окружено двойными кавычками.
- Если в поле есть двойная кавычка, то поле должно быть окружено двойными кавычками, а двойная кавычка внутри поля должна быть экранирована другой двойной кавычкой.
Вот пример запуска, который делает именно это на основе List<List<T>>
в качестве источника и OutputStream
в качестве пункта назначения.
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();
}
Вот как вы можете использовать его в сервлет:
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());
}
(обратите внимание, что на основе Европа локали использовать точку с запятой вместо запятой для CSV файлов, вы можете изменить)
Content-Disposition
от attachment
заставит Сохранить как диалог. Обратите внимание, что в MSIE есть неправильное поведение, которое не принимает filename
в качестве имени файла по умолчанию в диалоговом окне «» «Сохранить как», но вместо этого занимает последнюю часть пути.Так что если этот сервлет, например, вызывается http://example.com/csv, то вы получите csv
как имя файла по умолчанию. Скорее добавьте его в pathinfo, как следует http://example.com/csv/file.csv. Сервлет должен отображаться только на url-pattern
/csv/*
вместо /csv
.
, который может быть записан как «public static void writeCsv» (список Extends List >> csv, разделитель символов, вывод OutputStream) 'и изменить все' T' на '?' – user102008