web-dev-qa-db-ja.com

c#、Excel + csv:正しいエンコーディングを取得する方法は?

私はこれをかなり長い間試してきましたが、理解できません。 * .csvファイルを介してデータをExcelにエクスポートしようとしています。これまでのところうまく機能していますが、Excelでファイルを開くときにエンコードの問題がいくつかあります。

(左側が元の文字列、右側がExcelの結果):

Messwert(µm / m) ==> Messwert(µm / m)

Dümme Mässöng ==> Dümme Mässöng

Notepad ++は、ファイルが「ANSI asUTF8」(WTF?)でエンコードされていることを示しています。

だからここに私が有効な結果を得ようとしたさまざまな方法があります:明白な実装:

tWriter.Write(";Messwert(µm /m)");

より洗練されたもの(おそらく12以上のエンコーディングの組み合わせを試しました:)

tWriter.Write(Encoding.Default.GetString(Encoding.Unicode.GetBytes(";Messwert(µm /m)")));
tWriter.Write(Encoding.ASCII.GetString(Encoding.Unicode.GetBytes(";Messwert(µm /m)")));

等々

データを作成するメソッドのソースコード全体:

    MemoryStream tStream = new MemoryStream();
    StreamWriter tWriter = new StreamWriter(tStream);
    tWriter.Write("\uFEFF");

    tWriter.WriteLine(string.Format("{0}", aMeasurement.Name));
    tWriter.WriteLine(aMeasurement.Comment);
    tWriter.WriteLine();
    tWriter.WriteLine("Zeit in Minuten;Messwert(µm / m)");

    TimeSpan tSpan;
    foreach (IMeasuringPoint tPoint in aMeasurement)
    {
        tSpan = new TimeSpan(tPoint.Time - aMeasurement[0].Time);
        tWriter.WriteLine(string.Format("{0};{1};", (int)tSpan.TotalMinutes, getMPString(tPoint)));
    }

    tWriter.Flush();
    return tStream;

生成されたCSVファイル:

Dümme Mössäng
Testmessung die erste

Zeit in Minuten;Messwert(µm / m)
0;-703;
0;-381;
1;1039;
1;1045;
2;1457;
2;1045;
14
yas4891

この solution は、Javaアプリケーションの修正として記述されていますが、C#でも同様のことができるはずです。次のドキュメントも参照してください。 StreamWriter クラス、注釈ではバイト順マーク(BOM)を指します。

8
Ken Henderson

これは私にとって完璧に機能しました:

private const int WIN_1252_CP = 1252; // Windows ANSI codepage 1252

    this._writer = new StreamWriter(fileName, false, Encoding.GetEncoding(WIN_1252_CP));

CSVエンコーディングの問題(Microsoft Excel)

7
Fernando JS

次のことを試してください。

using (var sw = File.Create(Path.Combine(txtPath.Text, "UTF8.csv")))
{
  var preamble = Encoding.UTF8.GetPreamble();
  sw.Write(preamble, 0, preamble.Length);
  var data = Encoding.UTF8.GetBytes("懘荧,\"Hello\",text");
  sw.Write(data, 0, data.Length);
}

UTF8でエンコードされたCSVを書き込む前に、適切なUTF8プリアンブルをファイルに書き込みます。

6
Trevor Germain

「ANSIasUTF8」(WTF?)

NotePad ++はおそらく正しいでしょう。エンコーディングはUTF8(つまり、正しいUnicodeヘッダー)ですが、ANSIデータのみが含まれています(つまり、éは正しいUTF8の方法でエンコードされていないため、2バイトを意味します)。

または:それは逆です。これはANSI(ファイルヘッダーBOMなし)ですが、個々の文字のエンコードはUTF8であるか、UTF8のように見えます。これは、üおよび他の文字が複数の他の文字に拡張することを説明します。これを修正するには、ファイルをUnicodeとして強制的に読み取ります。

CSV(の一部)を投稿できる場合は、ソースで修正できる場合があります。

編集

コードを確認したので、StreamWriterを削除してTextWriterに置き換えることはできますか?また、BOMのハンドエンコーディングを削除します。これは必要ありません。 TextWriterを作成するときに、エンコーディングを指定できます(ASCIIは使用せず、UTF8を試してください)。

3
Abel

Trevor Germainは、正しいエンコード形式で保存するのを手伝ってくれました

using (var sw = File.Create(Path.Combine(txtPath.Text, "UTF8.csv")))
{
    var preamble = Encoding.UTF8.GetPreamble();  
    sw.Write(preamble, 0, preamble.Length);  
    var data = Encoding.UTF8.GetBytes("懘荧,\"Hello\",text");  
    sw.Write(data, 0, data.Length);
}
2
jAntoni

テキストファイルを16進エディタで開いて、実際の内容を確認することをお勧めします。 UTF-16のBOMは0xFEFFであり、書き込みコードは明らかにストリームに書き込んでいますが、残りの書き込みでは使用するエンコードを指定していません。StreamWriterのデフォルトのエンコードであるUTF-8を使用します。 。エンコーディングが混同されているようです。

ファイルを16進ビューでポップオープンしたときに、文字の間に0x00がたくさんある場合は、C#のEncoding.UnicodeであるUTF-16を使用しています。文字間に0x00がない場合、エンコーディングはおそらくUTF-8です。

後者の場合は、BOMをEF BB BFではなくFE FFに修正し、UTF-8エンコーディングで通常どおり読み取ります。

2
Mark H

StreamWriterを使用する私のシナリオでは、UTF8エンコーディングをStreamWriter対応のExcelに明示的に渡して、正しいエンコーディングを使用してファイルを読み取ることがわかりました。

詳細については、この回答を参照してください: https://stackoverflow.com/a/22306937/999048

0
michael_hook