プログラム 技術

文字列にカンマを含む場合のCSV書き出し対処法

中間ファイルとしてよくCSVファイルを使用することがありますが、時々書き出す文字列内に,(カンマ)が含まれている場合があります
その際にどのように対処する方法についてです

名前バージョン
OSWindows 11 Pro
C#.Net 8.0

書き出す際に"(ダブルクォーテーション)で囲う

書き出し

CSVファイルに書き出す際にあらかじめ"(ダブルクォーテーション)で囲って書き出します。これにより、CSVファイルを開いた際に変なところで区切られずに表示されます

public static void WriteCsv(string path, List<string[]> datas, string[] columnNames = null)
{
    using (var writer = new StreamWriter(path, false, Encoding.UTF8))
    {
        if (columnNames != null && columnNames.Length > 0)
        {
            // ダブルクォーテーションで囲んでカンマ区切りで書き出す
            writer.WriteLine(string.Join(",", columnNames.Select(x => $"\"{x}\"")));
        }

        foreach (var data in datas)
        {
            // ダブルクォーテーションで囲んでカンマ区切りで書き出す
            writer.WriteLine(string.Join(",", data.Select(x => $"\"{x}\"")));
        }
    }
}

読み込み

TextFieldParserクラスを使用してCSVファイルを読み込みます。これでダブルクォートで囲まれたフィールドも適切に処理できます

public static List<string[]> ReadCsv(string path, bool headerSkip = false)
{
    var datas = new List<string[]>();
    using (TextFieldParser parser = new TextFieldParser(path))
    {
        parser.TextFieldType = FieldType.Delimited;
        parser.SetDelimiters(",");

        if(headerSkip)
        {
            string[] headers = parser.ReadFields();
        }

        while (!parser.EndOfData)
        {
            string[] fields = parser.ReadFields();
            datas.Add(fields);
        }
    }

    return datas;
}

注意点

ただ、読み込む際にこの"(ダブルクォーテーション)を取り除くような処理を実装しておかないと予期せぬエラーの原因となるので注意が必要
また、複数のプログラムで扱う際には仕様として"(ダブルクォーテーション)で囲うということを定める必要がある

区切り文字を変える

そもそもの話として,(カンマ)以外を区切り文字として設定する方法です。今回はタブ区切りにしています

書き出し

通常のCSVファイルを書き出すときと同じように実装し、区切り文字だけをタブに置き換えるだけで実装できる

public static void WriteTsv(string path, List<string[]> datas, string[] columnNames = null)
{
    using (var writer = new StreamWriter(path, false, Encoding.UTF8))
    {
        if (columnNames != null && columnNames.Length > 0)
        {
            // タブ区切りで書き出す
            writer.WriteLine(string.Join("\t", columnNames));
        }

        foreach (var data in datas)
        {
            // タブ区切りで書き出す
            writer.WriteLine(string.Join("\t", data));
        }
    }
}

読み込み

読み込む際も特にひねりもなくタブで区切って読み込みだけです

public static List<string[]> ReadTsv(string path, bool headerSkip = false)
{
    var datas = new List<string[]>();
    using (var reader = new StreamReader(path, Encoding.UTF8))
    {

        if (headerSkip)
        {
            // ヘッダー行を読み飛ばす
            string[] headers = reader.ReadLine().Split('\t');
        }
        while (!reader.EndOfStream)
        {
            // タブ区切りで読み込む
            datas.Add(reader.ReadLine().Split('\t'));
        }
    }

    return datas;
}

注意点

書き出す際のファイル形式が「.tsv」とする必要がある。そこだけ注意!!

最後に

CSVファイルはよく使うファイル形式だと思うので今回のことを覚えておいて損はないと思います
また、今回のコードもGitHubにアップしているので参考にしてみてください

サンプルコード
BlogSampleCodeProjects/CsvTsvHelper at main · nasuton/BlogSampleCodeProjects · GitHub
BlogSampleCodeProjects/CsvTsvHelper at main · nasuton/BlogSampleCodeProjects · GitHub

Project for sample code used in the blog.(Blogで記載しているサンプルコード ...

GitHubへ

会社紹介

私が所属しているアドバンスド・ソリューション株式会社(以下、ADS)は一緒に働く仲間を募集しています

会社概要
「技術」×「知恵」=顧客課題の解決・新しい価値の創造

この方程式の実現はADSが大切にしている考えで、技術を磨き続けるgeekさと、顧客を思うloveがあってこそ実現できる世界観だと思っています
この『love & geek』の精神さえあれば、得意不得意はno problem!
技術はピカイチだけど顧客折衝はちょっと苦手。OKです。技術はまだ未熟だけど顧客と知恵を出し合って要件定義するのは大好き。OKです
凸凹な社員の集まり、色んなカラーや柄の個性が集まっているからこそ、常に新しいソリューションが生まれています

ミッション
私たちは、テクノロジーを活用し、業務や事業の生産性向上と企業進化を支援します

ホームページ
アドバンスド・ソリューション株式会社
アドバンスド・ソリューション株式会社

アドバンスド・ソリューションは主にMicrosoft製品を使用して、企業の生産性向上に取り組んでいます。要件定義から導入 ...

サイトへ移動

-プログラム, 技術
-