web-dev-qa-db-ja.com

opencsvの特定のヘッダーから読み取る方法は?

Csvファイルがあります。そこから特定の列を抽出したい例:たとえば、csvがあります:

id1,caste1,salary,name1
63,Graham,101153.06,Abraham
103,Joseph,122451.02,Charlie
63,Webster,127965.91,Violet
76,Smith,156150.62,Eric
97,Moreno,55867.74,Mia
65,Reynolds,106918.14,Richard

Opencsvを使用してヘッダーcaste1からデータのみを読み取るにはどうすればよいですか?

9

Opencsvには、列から名前で読み取るための組み込み機能はありません。

official FAQ example には、ファイルからの読み取り方法に関する次の例があります。

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
   // nextLine[] is an array of values from the line
   System.out.println(nextLine[0] + nextLine[1] + "etc...");
}

行にnextLine[1]を付けることにより、各行の2番目の列の値をフェッチするだけです(配列のインデックスはゼロベースであることを忘れないでください)。

したがって、あなたの場合、2行目から簡単に読み取ることができます。

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
   System.out.println(nextLine[1]);
}

ヘッダーから列インデックスを決定するより洗練された方法については、 Scott Conwayからの回答 を参照してください。

2
Magnilex

MagnilexとSparkyは、CSVReaderが列名による値の読み取りをサポートしていないという点で正しいです。しかし、そうは言っても、これを行うには2つの方法があります。

列名があり、デフォルトのCSVReaderがヘッダーを読み取る場合、最初にヘッダーで位置を検索してから、それを使用できます。

private int getHeaderLocation(String[] headers, String columnName) {
   return Arrays.asList(headers).indexOf(columnName);
}

したがって、メソッドは次のようになります(入力する必要のある多くのエラーチェックを省略します)

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
String [] nextLine;
int columnPosition;

nextLine = reader.readNext();
columnPosition = getHeaderLocation(nextLine, "castle1");

while ((nextLine = reader.readNext()) != null && columnPosition > -1) {
   // nextLine[] is an array of values from the line
   System.out.println(nextLine[columnPosition]);
}

私はあなたが時間に追われ、それがあなたが気にかけたたった一つのコラムであった場合にのみ上記をするでしょう。これは、openCSVが、CsvToBeanクラスとHeaderColumnNameMappingStrategyを使用して、ヘッダー列名と同じ変数を持つオブジェクトに直接変換できるためです。

したがって、最初にフィールドを持つクラスを定義します(実際には、必要なフィールドに入力するだけで済みます。余分なものは無視され、不足しているものはnullまたはデフォルト値です)。

public class CastleDTO {
   private int id1;
   private String castle1;
   private double salary;
   private String name1;

   // have all the getters and setters here....
}

次に、コードは次のようになります

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
HeaderColumnNameMappingStrategy<CastleDTO> castleStrategy = new HeaderColumnNameMappingStrategy<CastleDTO>();
CsvToBean<CastleDTO> csvToBean = new CsvToBean<CastleDTO>();

List<CastleDTO> castleList = csvToBean.parse(castleStrategy, reader);

for (CastleDTO dto : castleList) {
   System.out.println(dto.getCastle1());
}
7
Scott Conway

opencsv docs から:

バージョン4.2以降、特別なクラスを作成する必要さえない、CSVファイルを読み取る別の便利な方法があります。 CSVファイルにヘッダーがある場合は、CSVReaderHeaderAwareを初期化して、値をマップとして読み取り始めることができます。

_  reader = new CSVReaderHeaderAware(new FileReader("yourfile.csv"));
  record = reader.readMap();
_

.readMap()は単一のレコードを返します。すべてのレコードを取得するには、.readMap()を繰り返し呼び出して、最後(または最初の空の行)まで実行されたときにnullを取得する必要があります。例:

_Map<String, String> values;

while ((values = reader.readMap()) != null) {

    // consume the values here

}
_

このクラスには、さらにカスタマイズできる別のコンストラクターもあります。例:

_CSVReaderHeaderAware reader = new CSVReaderHeaderAware(
        new InputStreamReader(inputStream),
        0,      // skipLines
        parser, // custom parser
        false,  // keep end of lines
        true,   // verify reader
        0,      // multiline limit
        null    // null for default locale
);
_

私が見つけた1つの欠点は、リーダーが怠惰であるため、レコード数が提供されないことです。したがって、総数を知る必要がある場合(たとえば、正しい進行状況情報を表示するため)、別のリーダーを使用する必要があります。行を数えるためだけに。

CSVReaderHeaderAwareBuilder も利用できます

0
ccpizza