如何使用Servlet创建CSV文件?

4
我想从一个servlet下载CSV文件。我有一个对象数组(object[])中的数据,我需要将其写入CSV并下载。
你能帮我在servlet类中实现这个功能吗?
4个回答

11
Object[]如何代表CSV数据?它包含一行多列还是多行单列?我想Object[][]List<List<Object>>更合理。无论如何,创建CSV文件时必须遵循RFC4180规范,它基本上很简单,只有三个严格的规则:
  1. 字段之间使用逗号分隔。
  2. 如果一个字段中包含逗号,则该字段必须用双引号括起来。
  3. 如果一个字段中包含双引号,则该字段必须用双引号括起来,并且字段中的双引号必须用另一个双引号进行转义。
下面是一个示例,它基于List<List<T>>作为源和OutputStream作为目标,完全符合这些规则。
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();
}

以下是如何在Servlet中使用它的方法:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    List<List<Object>> csv = getItSomehow();
    response.setHeader("Content-Type", "text/csv");
    response.setHeader("Content-Disposition", "attachment;filename=\"file.csv\"");
    writeCsv(csv, ';', response.getOutputStream());
}

(请注意,基于欧洲的语言环境在CSV文件中使用分号而不是逗号,您可以自由更改)

attachmentContent-Disposition将强制出现“另存为”对话框。请注意,MSIE存在错误行为,它不会将filename作为“另存为”对话框中的默认文件名,而是将路径信息的最后一部分作为默认文件名。因此,如果此servlet例如是通过http://example.com/csv调用的,则默认文件名将是csv。最好将其附加到路径信息上,如下所示:http://example.com/csv/file.csv。该servlet应仅映射到/csv/*url-pattern,而不是/csv


可以编写为public static void writeCsv(List<? extends List<?>> csv, char separator, OutputStream output),并将所有的T更改为?。 - user102008

1

这是一次尝试:

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

    // Other stuff you know that I don't..

    Object[] data = search.getSearch();
    response.setContentType("text/csv");
    PrintWriter out = response.getWriter();
    for (Object d : data) {
        out.println(d.field1 + "," + d.field2 + "," + d.field3 + ...);
    }
}

如果你的字段包含逗号,则会出现错误。我让你自己想办法解决,因为这是一个快速的Google搜索


1

JavaCSV可以帮助您生成csv格式的表示。

然后,您可以使用以下方式编写文件:

  • response.getWriter()打印内容
  • response.setContentType("text/csv")

0

这里是我正在运行的一个生产servlet中的一些(已编辑以简洁和普遍性为目的)代码。使用下面的代码替换您特定的数据数组应该很容易。

public void doGet(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException {

        res.setContentType("application/octet-stream");
        res.setHeader("Content-Disposition", "attachment; filename=\"TSR.csv\"");
        try {
            // Write the header line
            OutputStream o = res.getOutputStream();
            String header = "ID,ControlNumber\n";
            o.write(header.getBytes());

            // Write the data lines
            Vector records = getRecords(); // Custom to my app
            Iterator i = records.iterator();
            while (i.hasNext()) {
                                // Custom data object; use your own
                StandardReportDTO sr = (StandardReportDTO) i.next();
                StringBuffer line = new StringBuffer();
                line.append(sr.getID());
                line.append(",");
                line.append(sr.getControlNumber());
                line.append("\n");
                o.write(line.toString().getBytes());
                o.flush();
            }

        } catch (Exception e) {
//          log.error(e);
        }
}

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