2

我正在尝试在 Web 应用程序上添加一个按钮,单击该按钮会下载一个 CSV 文件(很小,只有大约 4KB 大小)。

我已经制作了按钮并附加了一个监听器。文件也准备好了。我现在唯一需要做的就是创建在单击按钮时下载 csv 文件的实际事件。

假设“文件”(文件类型)是我正在使用的 csv 文件的名称,并且它已经准备就绪,这是我目前使用的方法:

public void downloadCSV(HttpServletRequest _request, HttpServletResponse _response, LogFileDetailCommand cmd) throws Exception {
     ServletOutputStream outStream = _response.getOutputStream();
     _response.setContentType("text/csv");  
     _response.setHeader("Content-Disposition", "attachment; filename=data.csv");
}

我意识到我错过了将文件写入 ServletOutputStream 的部分,但这是我坚持的部分。我知道 ServletOutputStream 类扩展了 OutputStream 类(http://docs.oracle.com/javaee/5/api/javax/servlet/ServletOutputStream.html),因此它继承了它的“写”方法,所以在一个理想的世界里我想简单地说“outStream.write(file);”,但我不能这样做,因为这些“write”方法只有 byte、byte[] 和 int 作为参数,而且不可能将文件传递给它们。

我应该怎么做才能将文件传递到 outStream 中?

(旁注:我应该在“_response.setContentLength();”中添加这个,如果是的话,我应该把什么参数放进去?)

Ps 我知道在完成 outStream 之后,我需要刷新和/或关闭它。

4

1 回答 1

2

您可以逐行读取 CSV 文件,并将该行写WriterHttpSerlvetResponse:

public class DownloadCsvServlet extends HttpServlet {

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {

    final File file = new File("/tmp/data.csv");

    response.setContentType("text/csv");

    response.setHeader("Content-Disposition",
            "attachment; filename=" + file.getName());

    final BufferedReader br = new BufferedReader(new FileReader(file));
    try {
        String line;
        while ((line = br.readLine()) != null) {
            response.getWriter().write(line + "\n");
        }
    } finally {
        br.close();
    }
}

}

如果同时使用 aReader和 a Writer,则将处理字符编码(例如,CSV 文件是具有 UTF-8 等编码的文本文件)。

此解决方案式传输,因此可能大文件中只有一小部分在内存中。

于 2013-08-07T10:34:52.750 回答