【问题标题】:How do I instruct CSVPrinter to not write a header line when adding a record?添加记录时如何指示 CSVPrinter 不写标题行?
【发布时间】:2019-02-08 14:14:43
【问题描述】:

我有一个由我正在编写的程序以外的程序创建的 CSV 文件,因此我无法更改标题。该文件的标题为ControllerID,Event,Number,ReaderID,Timestamp,TransactionID,。我已经为 CSVPrinter 指定了相同的标题,我用来将一行插入到同一个 CSV 中。但是,当打印机添加记录时,它会在新记录之前添加一个标题行,如下所示:

0,1,2688229830,3,2018-09-03 13:54,63
ControllerID,Event,Number,ReaderID,Timestamp,TransactionID
0,1,4900920,2,2018-09-03,15:15,176492

有问题的代码如下所示:

/* Add an entry to the TransactionLog CSV */
private static boolean logTransaction (
  int cid, int rid, boolean freeExit, long tsMS, long accNum, String reason
) {
  boolean added = false;
  int evt = freeExit ? 8 : 1;
  File transactLog = new File(Locations.getDatabaseDir(), "TransactLog.csv"),

  CSVFormat shortFormat = CSVFormat.DEFAULT.withQuote(null)
    .withAllowMissingColumnNames(true)/*.withTrailingDelimiter(true)*/
    .withHeader(Transaction.getHeader(false));
  // Attempt to read the last transaction ID and add 1 to it, to be used as ID of new transaction
  try (
    CSVParser shortParser = new CSVParser(new FileReader(transactLog), shortFormat);
    CSVPrinter shortWriter = new CSVPrinter(new FileWriter(transactLog, true), shortFormat);
  ) {
    // read in all the current records, getting the transactionID of the last record
    List<CSVRecord> shortRecords = shortParser.getRecords();
    int newTransId = 1;
    if (!shortRecords.isEmpty()) {
      CSVRecord last = shortRecords.get(shortRecords.size() - 1);
      String lastTransactionId = last.get("TransactionID");
      // add one to last transaction ID
      try {
        newTransId = Integer.parseInt(lastTransactionId) + 1;
      } catch (IllegalArgumentException IAEx) {
        newTransId = shortRecords.size() + 1;
        LOGGER.warn("Failed to determine last transaction ID from CSV ("
          + lastTransactionId + "); setting to recordCount (" + newTransId + ") ..."
        );
      }
    }
    // write the new transaction record
    Transaction t = new Transaction(cid, evt, accNum, rid, tsMS, newTransId, reason);
    List<String> tValues = t.asList(false), fValues = t.asList(true);
    shortWriter.printRecord(tValues);
    shortWriter.flush();
    added = true;
  } catch (IOException IOEx) {
    added = false;
    LOGGER.error(Util.getErrorTrace(
      "Failed to write transaction to \"" + transactLog.getAbsolutePath() + "\" CSV", IOEx
    ));
  }

  return added;
}

事务 POJO 的代码被省略,因为它与问题无关。

如何防止CSVPrinter 在输出行之前输出标题行? (CSV 文件已包含标题行。)

【问题讨论】:

    标签: java-7 apache-commons-csv


    【解决方案1】:

    为了不输出标题行,您需要将.withSkipHeaderRecord(true) 添加到与CSVPrinter 一起使用的CSVFormat 实例中,如下所示:

    CSVFormat skipFormat = CSVFormat.DEFAULT.withQuote(null)
      .withAllowMissingColumnNames(true).withTrailingDelimiter(true)
      .withHeader(Transaction.getHeader(false))
      .withSkipHeaderRecord(true).withIgnoreEmptyLines(true);
    

    .withIgnoreEmptyLines(true) 的调用是可选的。包含它是为了不保留空行/空白行。

    注意:如果你想输出一个标题行作为文件的第一行,当它被创建时,你可以将.withSkipHeaderRecord(true)更改为.withSkipHeaderRecord(csvFile.exists())。这是因为文件在创建之前并不存在,但在下一次写入记录时确实存在。

    【讨论】:

      猜你喜欢
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 2017-07-12
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 2015-06-02
      • 1970-01-01
      相关资源
      最近更新 更多