Java 如何从 Spring Controller 返回浏览器中的 CSV 数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22947751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 19:31:51  来源:igfitidea点击:

How to Return CSV Data in Browser From Spring Controller

javaspringspring-mvccsv

提问by David Williams

Let say I have CSV data in a string and want to return it from a Spring controller. Imagine the data looks like this

假设我有一个字符串中的 CSV 数据,并希望从 Spring 控制器返回它。想象一下数据是这样的

a,b,c 
1,2,3
4,5,6

No matter what I have tried, the newlines come out as literally '\n' in the response content, and if I double escape them as in "\n", the response just contains the double backslashes too. In general, how to I return plain text data with newlines in it without the newlines being modified? I know how to return plain text, but still, the content comes with escaped newlines... This is what I current have (using Spring 3.0.5, not by choice)

无论我尝试过什么,换行符都会在响应内容中以字面意义的 '\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,c\n1,2,3\n3,4,5";
    return new ResponseEntity<>(data, responseHeaders, HttpStatus.OK);
}

Which produces literally the string

从字面上产生字符串

"a,b,c\n1,2,3\n,3,4,5"

In the browser. How do I make it produce the correct data with new lines in tact as shown above?

在浏览器中。我如何使它产生正确的数据,如上图所示,新行完好无损?

采纳答案by Bart

You could write to the response directly using e.g.

您可以使用例如直接写入响应

@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");
}

Since the return type is voidand HttpServletResponseis declared as a method argument the request is assumed to be completed when this method returns.

由于返回类型是void并且HttpServletResponse被声明为方法参数,因此假定该方法返回时请求已完成。

回答by nickdos

Have you tried @ResponseBodyon your controller method?

你试过@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: Spring docs explain it here: http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-responsebody

编辑:Spring 文档在这里解释:http: //docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-responsebody

回答by Abdulhafeth Sartawi

You can use the library supercsv.

您可以使用库supercsv

<dependency>
  <groupId>net.sf.supercsv</groupId>
  <artifactId>super-csv</artifactId>
  <version>2.1.0</version>
</dependency>

Here is how to use it:

以下是如何使用它:

1- define your model class that you want to write as csv:

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- Do the following magic:

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();
    }
}