【问题标题】:Export csv file using stream with Play 2.1使用 Play 2.1 的流导出 csv 文件
【发布时间】:2013-06-04 12:54:35
【问题描述】:

我想允许客户端下载包含来自 ResultSet 的数据的 csv 文件。 我正在使用 java API (PLAY! 2.1)。

当 ResultSet 包含大量数据时,我的解决方案有效,但无法使用。

在我的控制器中:

ResultSet rs = st.executeQuery(sql);
String filename = "";
filename = createCSV(rs);.
response().setContentType("text/csv");
response().setHeader("Content-disposition","attachment; filename="+"export.csv");
return ok(new java.io.File("D:\\UTILIS~1\\user\\AppData\\Local\\Temp\\"+filename));

createCSV 方法:

public static String createCSV(ResultSet _resultSet) {
    String filename = "";
    try{
        ResultSetMetaData meta = _resultSet.getMetaData();

        // CSV file creation 
        File tempDir = new File(System.getProperty("java.io.tmpdir"));
        System.out.println(System.getProperty("java.io.tmpdir"));
        File tempFile = File.createTempFile("test", ".csv", tempDir);
        filename = tempFile.getName();
        FileWriter fileWriter = new FileWriter(tempFile, true);
        System.out.println(tempFile.getAbsolutePath());
        BufferedWriter bw = new BufferedWriter(fileWriter);

        for(int i = 1; i <= meta.getColumnCount(); i++)
        {
            String columnLabel = meta.getColumnName(i);
            bw.write(columnLabel + "|");
        }
        bw.write("\r\n");
        while(_resultSet.next())
        {
            for(int i = 1, count = meta.getColumnCount(); i <= count; i++){
                if (_resultSet.getObject(i) == null)
                    bw.write("null|");
                else
                    bw.write(_resultSet.getObject(i).toString() + "|");
            }
            bw.write("\r\n");
        }
        bw.close();
        tempFile.deleteOnExit();
    } catch(Exception e){
        e.printStackTrace();
    } 
    return filename;
}

为了节省内存,如何写入文件并使用流将其发送给用户。

我想我需要使用 Chunks,但我不知道该怎么做。

任何示例,提示?

【问题讨论】:

    标签: java download playframework-2.1


    【解决方案1】:

    您可以在文档中找到分块响应的示例:

    http://www.playframework.com/documentation/2.1.1/JavaStream

    您可以在生成 csv 内容时发送它。

    【讨论】:

    • 我看到了这个文档,但我不确定如何去做。我暂时使用了这个(createCSV 方法): BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path+filename), "US-ASCII"));这在控制器中: return ok(new java.io.File(path+filename));你能举一个你的解决方案的例子吗?
    • 在示例中的方法 registerOutChannelSomewhere(Chunks.Out out) 中生成您的记录集,而不是创建文件,而是使用 out 对象流式传输 csv 内容。
    • 它有效,谢谢!还有一个问题,如果我必须从数据库中获取数据,那么在哪里进行请求的最佳位置?在 registerOut 函数中?
    • 是的,在 registerOut 函数中。
    • 感谢您的快速回复!
    【解决方案2】:

    Ok方法以字节数组为参数

    所以,获取文件内容的字节数组并尝试

    return ok(s.toByteArray()).as("application/octet-stream");

    See this获取文件的字节数组

    【讨论】:

    • 我想我理解错了你的问题。您可以将其写入 StringBuilder 并获取其字节数组并返回它,而不是写入文件。
    • 会被解析成csv文件吗?
    【解决方案3】:

    1) 从响应中获取输出流

    2) 将此输出流传递给 createCSV 方法并直接写入

    您还可以通过使用 ZipOutputStream 装饰输出流来压缩结果。

    注意:不需要创建临时文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-27
      • 1970-01-01
      • 2023-04-01
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多