Лучше использовать сервлет для этого. Необработанный код Java не входит в файл JSP, это просто рецепт для проблемы с обслуживанием .
Для начала создайте простой служебный класс Java, который принимает, например, List<List<T>>
или List<Data>
(где Data
представляет одну строку), представляющий содержимое CSV, и OutputStream
в качестве аргументов метода и логику записи, которая выполняет задачу копирования данных.
Как только вы это заработаете, создайте класс Servlet, который принимает некоторый идентификатор файла CSV в качестве параметра запроса или pathinfo (я рекомендую использовать pathinfo, поскольку определенный веб-браузер, разработанный командой из Редмонда, не сможет обнаружить имя файла / mimetype иначе) использует идентификатор для получения List<List<T>>
или List<Data>
откуда-то и записывает его в OutputStream
из HttpServletResponse
вдоль набора правильных заголовков ответа.
Вот основной базовый пример:
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();
}
Вот пример того, как вы можете его использовать:
public static void main(String[] args) throws IOException {
List<List<String>> csv = new ArrayList<List<String>>();
csv.add(Arrays.asList("field1", "field2", "field3"));
csv.add(Arrays.asList("field1,", "field2", "fie\"ld3"));
csv.add(Arrays.asList("\"field1\"", ",field2,", ",\",\",\""));
writeCsv(csv, ';', System.out);
}
А внутри сервлета вы можете сделать:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = request.getPathInfo();
List<List<Object>> csv = someDAO().list();
response.setHeader("content-type", "text/csv");
response.setHeader("content-disposition", "attachment;filename=\"" + filename + "\"");
writeCsv(csv, ',', response.getOutputStream());
}
Отобразите этот сервлет на что-то вроде /csv/*
и вызовите его как-то вроде http://example.com/context/csv/filename.csv
. Это в основном все. Имя файла в pathinfo важно, потому что определенный веб-браузер, разработанный командой из Редмонда, игнорирует часть filename
заголовка Content-Disposition
и использует вместо этого последнюю часть пути URL.