Как вернуть данные CSV в браузере из Spring Controller
Допустим, у меня есть данные CSV в строке и я хочу вернуть их с контроллера Spring. Представьте, что данные выглядят так
a,b,c
1,2,3
4,5,6
независимо от того, что я пробовал, новые строки выходят как буквально "n" в содержании ответа, и если я дважды избегаю их, как в "n", ответ также содержит двойные косые черты. В общем, как вернуть текстовые данные с новыми строками без изменения новых строк? Я знаю, как вернуть обычный текст, но все же, контент поставляется с экранированными новыми строками... Это то, что у меня есть (используя Spring 3.0.5, а не по выбору)
@RequestMapping(value = "/api/foo.csv")
public ResponseEntity<String> fooAsCSV() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Type", "text/plain; charset=utf-8");
String data = "a,b,cn1,2,3n3,4,5";
return new ResponseEntity<>(data, responseHeaders, HttpStatus.OK);
}
который производит буквально строку
"a,b,cn1,2,3n,3,4,5"
в браузере. Как заставить его производить правильные данные с новыми строками в такте, как показано выше?
3 ответов
вы можете написать ответ напрямую, используя, например,
@RequestMapping(value = "/api/foo.csv")
public void fooAsCSV(HttpServletResponse response) {
response.setContentType("text/plain; charset=utf-8");
response.getWriter().print("a,b,c\n1,2,3\n3,4,5");
}
Так как тип возврата -void
и HttpServletResponse
объявлен в качестве аргумента метода запрос считается завершенным, когда этот метод возвращает.
ты пробовал @ResponseBody
на вашем методе контроллера?
@RequestMapping(value = "/api/foo.csv")
@ResponseBody
public String fooAsCSV(HttpServletResponse response) {
response.setContentType("text/plain; charset=utf-8");
String data = "a,b,c\n1,2,3\n3,4,5";
return data;
}
Edit: весенние документы объясняют это здесь: http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-responsebody
вы можете использовать библиотеку supercsv.
<dependency>
<groupId>net.sf.supercsv</groupId>
<artifactId>super-csv</artifactId>
<version>2.1.0</version>
</dependency>
вот как его использовать:
1-Определите класс модели, который вы хотите написать как csv:
public class Book {
private String title;
private String description;
private String author;
private String publisher;
private String isbn;
private String publishedDate;
private float price;
public Book() {
}
public Book(String title, String description, String author, String publisher,
String isbn, String publishedDate, float price) {
this.title = title;
this.description = description;
this.author = author;
this.publisher = publisher;
this.isbn = isbn;
this.publishedDate = publishedDate;
this.price = price;
}
// getters and setters...
}
2 - Сделайте следующее волшебство:
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
/**
* This Spring controller class implements a CSV file download functionality.
*
*/
@Controller
public class CSVFileDownloadController {
@RequestMapping(value = "/downloadCSV")
public void downloadCSV(HttpServletResponse response) throws IOException {
String csvFileName = "books.csv";
response.setContentType("text/csv");
// creates mock data
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"",
csvFileName);
response.setHeader(headerKey, headerValue);
Book book1 = new Book("Effective Java", "Java Best Practices",
"Joshua Bloch", "Addision-Wesley", "0321356683", "05/08/2008",
38);
Book book2 = new Book("Head First Java", "Java for Beginners",
"Kathy Sierra & Bert Bates", "O'Reilly Media", "0321356683",
"02/09/2005", 30);
Book book3 = new Book("Thinking in Java", "Java Core In-depth",
"Bruce Eckel", "Prentice Hall", "0131872486", "02/26/2006", 45);
Book book4 = new Book("Java Generics and Collections",
"Comprehensive guide to generics and collections",
"Naftalin & Philip Wadler", "O'Reilly Media", "0596527756",
"10/24/2006", 27);
List<Book> listBooks = Arrays.asList(book1, book2, book3, book4);
// uses the Super CSV API to generate CSV data from the model data
ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(),
CsvPreference.STANDARD_PREFERENCE);
String[] header = { "Title", "Description", "Author", "Publisher",
"isbn", "PublishedDate", "Price" };
csvWriter.writeHeader(header);
for (Book aBook : listBooks) {
csvWriter.write(aBook, header);
}
csvWriter.close();
}
}