在Java servlet中创建并下载CSV文件

12

我正在开发一个Java ExtJS应用程序,需要创建并下载CSV文件。

  • 点击按钮后,我希望CSV文件可以下载到客户端计算机上。
  • 在按钮监听器中,我使用AJAX调用一个servlet。在servlet中,我创建了一个CSV文件。

我不想将CSV文件保存在服务器上。我希望动态地创建文件并提供下载选项。我希望将文件内容作为字符串创建,然后将其作为文件提供,在浏览器中以下载模式打开(我已经在其他语言中实现了这一点,但不确定如何在Java中实现)。

以下是我仅用于创建CSV文件的代码,但如果可以只下载文件作为CSV文件,则不需要创建或保存CSV文件。

public String createCSV() {
    try {
        String filename = "c:\\test.csv";
        FileWriter fw = new FileWriter(filename);
        fw.append("XXXX");
        fw.append(',');
        fw.append("YYYY");
        fw.append(',');
        fw.append("ZZZZ");
        fw.append(',');
        fw.append("AAAA");
        fw.append(',');
        fw.append("BBBB");
        fw.append('\n');

        CSVResult.close();

        return "Csv file Successfully created";
    } catch(Exception e) {
        return e.toString();
    }
}

有人可以帮我吗。

谢谢


1
这是你要的答案 https://dev59.com/uE7Sa4cB1Zd3GeqP7eS1。 - Abesalomi Gogatishvili
3个回答

34

我已经找到解决方案并在下面发布。

public void doGet(HttpServletRequest request, HttpServletResponse response)
{
    response.setContentType("text/csv");
    response.setHeader("Content-Disposition", "attachment; filename=\"userDirectory.csv\"");
    try
    {
        OutputStream outputStream = response.getOutputStream();
        String outputResult = "xxxx, yyyy, zzzz, aaaa, bbbb, ccccc, dddd, eeee, ffff, gggg\n";
        outputStream.write(outputResult.getBytes());
        outputStream.flush();
        outputStream.close();
    }
    catch(Exception e)
    {
        System.out.println(e.toString());
    }
}

在这里我们不需要将文件保存在服务器上。

谢谢


在这个例子中,model.closeConnection()是什么?我没有看到任何叫做model的对象。 - Moob
这里的“model”只是一个对象的名称,它将调用closeConnection()函数来关闭数据库连接。这仅仅是为了确保连接被关闭。您可以根据自己的设计在代码中的任何位置放置它。 - Gourav
好的。只是想知道它是否应该包含在你的示例中?原帖没有提到数据库连接。这可能会让其他人感到困惑,就像我一样。只是说一下 ;) - Moob
我尝试了你的代码,但对我不起作用。你是如何进行ajax调用的?我只是使用了$.get( "SERVLETNAME", { parameters }, function( ) {}); - progNewbie
嗨Gourav!你的解决方案很完美,但我有两个问题: 1)我要下载的文件必须是TXT格式,并且必须有更多的行。 2)如果我从浏览器调用servlet,它可以工作,但如果我使用AJAX进行“post”调用,我只能恢复文本,而不能自动下载文件。 你能告诉我我错在哪里吗? 谢谢 - pigobyte

6

首先,您需要获取HttpServletResponse对象,以便可以将文件流式传输到其中。

注意:此示例是我为其中一个项目编写的,并且它可以在Java 7上运行。

假设您已经获得了HttpServletResponse,您可以使用以下方式流式传输文件。这样,文件将保存在客户机器上。

public void downloadFile(HttpServletResponse response){ 

        String sourceFile = "c:\\source.csv";
        try {
            FileInputStream inputStream = new FileInputStream(sourceFile);
            String disposition = "attachment; fileName=outputfile.csv";
            response.setContentType("text/csv");
            response.setHeader("Content-Disposition", disposition);
            response.setHeader("content-Length", String.valueOf(stream(inputStream, response.getOutputStream())));

        } catch (IOException e) {
            logger.error("Error occurred while downloading file {}",e);
        }
}

流方法应该像这样。
private long stream(InputStream input, OutputStream output) throws IOException {

    try (ReadableByteChannel inputChannel = Channels.newChannel(input); WritableByteChannel outputChannel = Channels.newChannel(output)) {
        ByteBuffer buffer = ByteBuffer.allocate(10240);
        long size = 0;

        while (inputChannel.read(buffer) != -1) {
            buffer.flip();
            size += outputChannel.write(buffer);
            buffer.clear();
        }
        return size;
    }
}

这段代码的作用是,从源文件中获取输入流,然后将该流写入HttpServletResponse的输出流中。由于此代码完美地运行了,因此应该可以正常工作。希望这有所帮助。抱歉我的英语不好。


如果CSV文件已经被创建并存储在服务器上,那么上述方法将会起作用。感谢您的回答和支持。这确实有效。但我的需求有所不同。我已经找到了解决方案并进行了发布。 - Gourav

0

我想在gaurav的答案中添加一些内容。最近我在我的一个项目中需要实现这个功能,但使用JavaScript是不可行的,因为我们必须支持IE 9。IE 9有什么问题吗?(使用jQuery和html导出CSV),请参见链接中的第二个答案。

我需要一种简单的方法将数据库查询的ResultSet转换为表示相同数据的字符串,以CSV格式呈现。为此,我使用了http://opencsv.sourceforge.net/,它提供了一种从ResultSet获取String的简单方法,其余部分与上面的答案相同。

项目源文件夹中的示例给出了很好的示例。


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