创建CSV文件而不将其保存到文件系统中

时间:2017-01-25 13:23:18

标签: java csv spring-mvc spring-boot inputstream

我创建了一个Java程序来创建csv文件,将数据写入其中,然后将其内容发送到服务器。

在当地,一切正常。但问题是我没有对服务器的写访问权限(权限被拒绝问题)。

所以,我不能做任何chmod 777

我正在寻找一种方法来创建csv文件而不保存到文件系统中。写入流或流的东西。我真的不知道它是如何工作的。 有什么帮助吗?

这是我到目前为止所做的:

  public void exportAllToCSV(@PathVariable int id,HttpServletResponse response) throws IOException
 String csvFile="test.csv";
 File file = new File("test.csv");
 //some treatments to get datas (headers and values)


  FileWriter writer = new FileWriter(csvFile);
  CsvBuilder.writeLine(writer, headers);
  CsvBuilder.writeLine(writer, values);
  writer.flush();
  writer.close();
  response.setContentType("text/csv");
  response.setHeader("Content-Disposition", "attachment; filename=" + csvFile);
  final BufferedReader br = new BufferedReader(new FileReader(file));

  try {
        String line;

        while ((line = br.readLine()) != null) {
            response.getWriter().write(line + "\n");
        }
    } finally {
        br.close();
    }

    try {
        file.delete(); // I delete the file
    } catch (Exception e) {
        e.printStackTrace();
    }

5 个答案:

答案 0 :(得分:3)

您可以尝试直接写回复:

Writer writer =  response.getWriter();

CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
writer.close();

response.setContentType("text/csv");
response.setHeader("Content-Disposition","attachment; filename=" + csvFile);

如果由于某种原因无法使用,并且您也不允许使用临时文件,则可以尝试使用这种非常丑陋的内存变体。

List<Integer> output = new LinkedList<>();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new OutputStream() {
    @Override
    public void write(int b) throws IOException {
        output.add(b);
    }
}));
// write all the things via CsvBuilder
final BufferedReader reader = new BufferedReader(new InputStreamReader(new InputStream() {
    @Override
    public int read() throws IOException {
        if (output.size() > 0) {
            return output.remove(0);
        }
        return -1;
    }
}));

答案 1 :(得分:2)

如果允许临时文件,您可以尝试:

File temp = File.createTempFile("test.csv", ".csv");

这些文件是在系统的用户存储中创建的,所以像Windows中的“C:\ Users [Username] \ AppData”或类似的东西。我不知道确切的路径,但现在这不应该是重要的。

查看Java中存在的所有类型的OutputStream,其中不仅仅是FileOutputStream: https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html 检查子类。

答案 2 :(得分:2)

假设CsvBuilder.writeLine(...)只接受java.io.Writer的实例,为什么不使用java.io.StringWriterjava.util.Scanner

// ...

StringWriter writer = new StringWriter();
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();

response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=test.csv");

Scanner scanner = new Scanner(new StringReader(writer.toString()))
while (scanner.hasNext()) {
   response.getWriter().write(scanner.next() + "\n");
}

// ...

然而,我认为Andrei Makarevich直接使用response.getWriter()的答案可能是最具前瞻性的方法。虽然,我不确定是否会CsvBuilder添加换行符,因为您明确添加了这些换行符了??

答案 3 :(得分:0)

您可以使用StringBuilderWriter来创建编写器而不是FileWriter

addTest

答案 4 :(得分:0)

万一有人还在寻找答案,下面的代码对我来说很完美

导入以下依赖项

    <dependency>
        <groupId>net.sourceforge.javacsv</groupId>
        <artifactId>javacsv</artifactId>
        <version>2.0</version>
    </dependency>

在下面的代码中,我将数据写入ByteArrayOutputStream而不是FileWriter

  ByteArrayOutputStream out = new ByteArrayOutputStream();
  CsvWriter csvWriter = new CsvWriter(new BufferedOutputStream(out), ',', Charset.forName("UTF-8"));
  String[] data = new String[] { "fieldValueA", "fieldValueB", "fieldValueC" };
  csvWriter.writeRecord(data);
  csvWriter.close();