【Apex】CSV読み込み。カンマを含む文字データを分割する。

Salesforce

CSVの文字データにカンマが含まれる場合

1,"カンマ,を含む文字"

これをapexで読み込む際、Splitで単純に分割するとこんな感じの分割になってしまう。

1列目:1
2列目:"カンマ
3列目:を含む文字"

ダブルクォーテーションで囲まれたカンマを文字として扱いたい場合、apexであれば1文字ずつ判定する必要がある。

サンプルはこんな感じ。
1行分のデータを食わせると、カンマで分割したデータをリストに突っ込んで返してくれる。

/**
 * CSVカンマ区切り分割処理.
 * データにカンマを含み単純にsplitできない場合に対応
 * @param line 1行分データ
 * @return 分割したデータリスト
 */
public List<String> csvSplit(String line) {
    List<String> retList = new List<String>();
    String data = ''; //1データ分
    Boolean doubleQuoteFlag = False; //True=ダブルクォートの中、False=ダブルクォートの外
    
    For (Integer i = 0; i < line.length(); i++) {
        // 1文字ずつ判定
        String s = line.mid(i, 1);
        If (s.equals('"')) {
            // ダブルクォートの場合、中⇔外を反転
            doubleQuoteFlag = !doubleQuoteFlag;
        } else if (s.equals(',') && doubleQuoteFlag) {
            // ダブルクォートの中のカンマはデータとして扱う
            data += s;
        } else if (s.equals(',') && !doubleQuoteFlag) {
            // ダブルクォートの外のカンマ発見で区切り
            retList.add(data);
            data = '';
        } else {
            data += s;
        }
    }
    // 最終列のデータをリストに設定
    retList.add(data);
    return retList;
}

上記サンプルはダブルクォーテーションのエスケープに対応していないのであしからず。
なお囲みのダブルクォーテーションはついでに取っ払っています。

デバッグモードで動作確認

String line = '1,"カンマ,を含む文字"';
TestClass test = new TestClass();
List<String> cols = test.csvSplit(line);

for (Integer i = 0; i < cols.size(); i++) {
	System.debug((i + 1) + '列目:' + cols.get(i));
}

期待とおりの動作になりました。

USER_DEBUG [6]|DEBUG|1列目:1
USER_DEBUG [6]|DEBUG|2列目:カンマ,を含む文字

コメント

タイトルとURLをコピーしました