如何使用Java Servlet下载CSV文件?

4

我有一个Java Servlet文件样例,但它只能导出到本地文件。但是当点击下载按钮时,我需要下载CSV文件。这里是Servlet类,我需要在这里添加哪些代码来下载CSV文件呢?

import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CsvFile extends HttpServlet { 
public void doGet (HttpServletRequest request,HttpServletResponse response) 
throws ServletException,IOException  {
try
{
      PrintWriter out = response.getWriter();
      String filename = "c:\\csv\\myfile.csv";
      FileWriter fw = new FileWriter(filename);

      fw.append("Employee Code");
      fw.append(',');
      fw.append("Employee Name");
      fw.append(',');
      fw.append("Employee Address");
      fw.append(',');
      fw.append("Employee Phone");
      fw.append(',');
      fw.append("Employee ZipCode");
      fw.append('\n');

      fw.append("E1");
      fw.append(',');
      fw.append("Vineet");
      fw.append(',');
      fw.append("Delhi");
      fw.append(',');
      fw.append("224277488");
      fw.append(',');
      fw.append("110085");
      fw.append('\n');

      fw.append("E2");
      fw.append(',');
      fw.append("Amar");
      fw.append(',');
      fw.append("Delhi");
      fw.append(',');
      fw.append("257765758");
      fw.append(',');
      fw.append("110001");
      fw.append('\n');

      fw.append("E3");
      fw.append(',');
      fw.append("Amit");
      fw.append(',');
      fw.append("Delhi");
      fw.append(',');
      fw.append("257685858");
      fw.append(',');
      fw.append("110005");
      fw.append('\n');

      fw.append("E4");
      fw.append(',');
      fw.append("Suman");
      fw.append(',');
      fw.append("Delhi");
      fw.append(',');
      fw.append("266447678");
      fw.append(',');
      fw.append("110081");
      fw.append('\n');


      fw.flush();
      fw.close();
      out.println("<b>Csv file Successfully created.</b>");

} 
catch (Exception ex) {
ex.printStackTrace ();
}
}
}

你是在尝试将数据导入到Excel吗? - Romain Hippeau
2个回答

6

您正在将文件写入而不是HTTP响应。

  • 您需要将CSV写入HttpServletResponse#getWriter()
  • 您需要将Content-Disposition标头设置为attachment,以在Web浏览器中强制出现“另存为”对话框,最终包括filename属性。有一个(主要?)警告:MSIE浏览器不会使用指定的filename作为保存为对话框中的实际文件名,而是使用URL的pathinfo的最后一部分。
  • 您需要将Content-Type标头设置为text / csv,以指示Web浏览器它是什么类型的文件,以便在最终用户选择打开而不是保存时找到正确的关联应用程序。通常,在Windows机器上,默认情况下将MS Excel与该内容类型相关联。

为了达到这些要求,您需要创建一个CsvServlet,其基本上在doGet()方法中执行以下操作。

String filename = request.getPathInfo().substring(1); // get rid of leading `/`
response.setHeader("Content-Type", "text/csv");
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
PrintWriter writer = response.getWriter();
writer.append("CSV content");
// ...

结束了。顺便说一下,flush()close()并不是严格必要的,但如果您想避免在请求链中后面有其他内容附加到响应体(这严格来说应该发生,但它只会在服务器日志中发出IllegalStateException和/或IOException,而不是扭曲响应),则很有用。

然后,在web.xml中映射CsvServlet,使用/csv/*作为url-pattern,并通过http://example.com/context/csv/filename.csv调用它。


话虽如此,您可能更喜欢一个真正的CSV格式化程序/编写器,它可以将String[][]List<List<String>>很好地写入OutputStreamWriter,从而尊重CSV格式化规则。可能会发生字段值本身包含引号或逗号的情况,这种情况下CSV格式将会被破坏。

另请参阅:


如何调用CsvServlet?web.xml中的条目看起来是什么样子的? - progNewbie

3

将内容类型设置为application/vnd.ms-excel并设置响应头的content-disposition属性 response.setHeader("Content-Disposition", "attachment; filename=\"myfile.csv\"");


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接