【问题标题】:How to append new row using Apache Common CSV CSVPrinter?如何使用 Apache Common CSV CSVPrinter 添加新行?
【发布时间】:2019-09-25 19:38:06
【问题描述】:

我有这个类包含使用Apache Common CSV library 1.5 生成 CSV 文件的方法

public class CSVGenerator {

    private static final String CSV_FILE = "./credentials.csv";
    private static CSVPrinter csvPrinter;

    public static void generateCSV(String FirstName, String LastName, String DOB) {


        try {
            BufferedWriter writer = Files.newBufferedWriter(Paths.get(CSV_FILE) );

            csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT
                    .withHeader("FirstName", "LastName", "DOB"));

            csvPrinter.printRecord(FirstName, LastName, DOB);
            csvPrinter.flush();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我的主类中有一个方法,这个方法会调用方法generateCSV()几次。
如何编写新行并将其附加到现有的 CSV 文件?使用我当前的实现,它将继续覆盖我的第一行。

更直接的解决方案是在任何 Java 集合(数组或列表)中收集我的所有数据,然后在最后迭代集合并将其一次性写入 CSV。但我不会那样做。我更喜欢将一行写入 CSV ,执行其他操作,然后再次调用该方法以写入新行并将其附加到现有的 CSV 中。

谢谢。

【问题讨论】:

    标签: java apache-commons-csv


    【解决方案1】:

    使用APPEND 选项:

    BufferedWriter writer = Files.newBufferedWriter(
            Paths.get(CSV_FILE), 
            StandardOpenOption.APPEND, 
            StandardOpenOption.CREATE);
    

    您必须进行设置,以使以下一个为真:

    1. 开始之前,请确保输出文件为空或不存在;
    2. 仅在第二次和后续调用generateCSV 时使用APPEND 选项

    顺便说一句,您在每次调用 generateCSV 时都会创建一个新的 BufferedWriterCSVPrinter,而不是关闭任何一个。这很浪费,您可能应该在构造函数中创建它们,实现Closeable,并实现close() 方法来清理。然后将调用代码包装在实例化 generateCSV 的 try-with-resources 中。

    【讨论】:

    • 谢谢吉姆。我添加了选项 StandardOpenOption.APPEND ,但它抛出了我 java.nio.file.NoSuchFileException: .\credentials.csv at java.nio.file.Files.newOutputStream(Files.java:216) at java.nio.file.Files.newBufferedWriter(Files.java:2860) 。当我删除该选项时,它运行良好(没有抛出异常),但我只是不断被覆盖并获得 1 行。在运行代码之前,我已经确定 csv 不存在。
    • 糟糕,忘记包含CREATE 选项。答案已更新。
    【解决方案2】:

    这是一种更简单的方法。在检查文件是否存在之后,您应该实例化 Writer 对象,否则将创建实例化文件,并且每次您都会将 file.exists() 设为 true。 如果文件存在,则需要使用 withSkipHeaderRecord() 创建 CSVPrinter,否则使用 header() 方法的任何实现。 FileWriter 构造函数采用带有 File 参数的可附加参数。如果有文件,则必须将可附加参数设为 true。

    File file = new File(filePath.concat("/").concat(fileName));
            if(file.exists()) {
                fileWriter = new FileWriter(file, true);
                csvPrinter = new CSVPrinter(fileWriter, CSVFormat.DEFAULT.withSkipHeaderRecord());
            }
            else {
                fileWriter = new FileWriter(file);
                csvPrinter = new CSVPrinter(fileWriter, CSVFormat.DEFAULT.withHeader("FirstName", "LastName", "DOB"));
                
            }
    

    【讨论】:

      【解决方案3】:

      检查https://stackoverflow.com/a/56034569/3602015中告知的条件后的解决方案

          String data = "stackoverflow";
          File file = new File("tmp/sample.csv");
          BufferedWriter writer;
          CSVPrinter csvPrinter;
          if (!file.exists()) {
              writer = Files.newBufferedWriter(Paths.get("tmp/sample.csv"));
              csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader("S No","Col1"));
          } else {
              writer = Files.newBufferedWriter(Paths.get("tmp/sample.csv", StandardOpenOption.APPEND
                      , StandardOpenOption.CREATE);
              csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT);
          }
      
          csvPrinter.printRecord("1", data);
          csvPrinter.flush();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-10
        • 2019-02-08
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        相关资源
        最近更新 更多