質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

8238閲覧

C# csv出力した文字列(ひらがな、漢字)をExcelで文字化けしないで表示したい

mia1620

総合スコア12

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2019/09/18 05:03

前提・実現したいこと

C#を使ってExcelファイルから文字(ひらがな+漢字)を取得し、csvファイルに書き出したものを文字化けせずにExcelで見れるようにしたい。
また、文字列が一行分あけてcsv書き込みされるので一行あかないようにしたい。

Excelファイル

ABC
みゆき123.3
11.2
ikeda22.5

発生している問題・エラーメッセージ

Excelで開くとひらがなと漢字で書いている部分が文字化けしてしまう。
CSVファイルをメモ帳でひらくとひらがなも文字列も正常に見れる。

Excelから読み込んで書き込んでいる部分とヘッダーの間に一行空いてしまう。

ABC
文字化け123.3
文字化け11.2
ikeda22.5
エラーメッセージ

該当のソースコード

C#

1//Excelデータの読込 2Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application(); 3Workbook wb = ExcelApp.Workbooks.Open(ExcelbookFileName); 4Worksheet ws1 = wb.Sheets[1]; 5ws1.Select(Type.Missing); 6int i; 7int n = 5; 8string[] name=new string[0]; 9string[] ID=new string[0]; 10for (i = 0; i < 10; i++) 11{ 12 Array.Resize(ref name,name.Length + 1); 13 Range range = ExcelApp.get_Range("A" + n, Type.Missing); 14 if (range != null) 15 { 16 var val = range.Value2; 17 name[name.Length - 1] = val; 18 } 19 20 Array.Resize(ref ID, ID.Length + 1); 21 Range range2 = ExcelApp.get_Range("C" + n, Type.Missing); 22 if (range2 != null) 23 { 24 var val2 = range2.Value2; 25 ID[ID.Length - 1] = val2; 26 } 27 n++; 28} 29wb.Close(); 30 31//CSVファイルを作成・書き込み 32string Path = @"C:\Users"; 33StreamWriter sw = new StreamWriter(Path); 34string[] s1 = { "Name", "", "ID" }; 35string s2 = string.Join(",", s1); 36sw.WriteLine(s2); 37sw.Close(); 38FileStream fs = new FileStream(Path,FileMode.Open,FileAccess.ReadWrite,FileShare.None); 39StreamReader sr = new StreamReader(fs); 40 StreamWriter sw2 = new StreamWriter(fs); 41string str = sr.ReadToEnd(); 42string[] s3 = {name[i], "", ID[i]}; 43string s4 = string.Join(",", s3); 44Str = str + "\n" + s4; 45fs.Position = 0; 46fs.SetLength(0); 47sw2.Write(str); 48sw2.Flush(); 49sr.Close();

試したこと

文字列のエンコードなど調べてみて試してみましたが何も変わりませんでした。
Excelから読み込んだ文字列をコンソールで表示してみましたが、正常に表示されました。

補足情報(FW/ツールのバージョンなど)

VisualStudio2015

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

CSV

1Name,,ID 2みゆき,,123.3 3要,,11.2 4ikeda,,22.5

このデータをテキストエディタにて文字コードを指定して保存し、エクセルで読み込みました。

EXCEL2019にて試した結果は

文字コード結果メモ帳
SHIFT-JISOKOK
UTF-8 BOM無文字化けOK
UTF-8 BOM有OKOK
UNICODE BOM無文字化け文字化け
UNICODE BOM有文字化けしないがカンマで分割されないOK

となりました。
エンコードなど調べてみて試してみました
とのことですが、うまくコード変換されていなかったのではないでしょうか。
試したコードを提示されると問題点が分かるかもしれません。

ちなみに、提示されたコードにて出力するとUTF-8 BOM無で出力されます。

投稿2019/09/18 06:56

編集2019/09/18 07:03
YAmaGNZ

総合スコア10222

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mia1620

2019/09/18 07:32

文字コード別に調べていただき、ありがとうございます。 UTF-8にBOMの有り無しがあることを知りませんでしたので勉強になりました。Shift_JISもしてみてはいたのですが、エンコードの位置を間違えていたようです。(お恥ずかしいところですが、ヘッダー以外の部分のみ書き込み時にエンコードしていました。) 詳しく教えていただき、ありがとうございました。
guest

0

ベストアンサー

ヘッダとExcelデータとの間に1行空いてしまうのは、以下の"\n"が原因です。
Str = str + "\n" + s4;
strは一度sw.WriteLine(s2);で書き込んだヘッダ情報を再度読み込んだものですが、WriteLineなので終端に改行文字が含まれます。
このため、上式に含まれる"\n"により2回改行文字が含まれる格好となります。

また、文字化けの件ですが、生成ファイルをメモ帳等で開くとどうなるか確認した方がよいでしょう。

ところで、csv書き込み部分はループになっていないのですが、実際はループで書き込んでいるのですよね?
あと、ヘッダ書き込み後、わざわざ出力先ファイルを閉じて、再度Excelデータを書き込むということを行っているように見えるのですが、一度に書き込みした方が効率的です。
そうしない理由が何かあるのでしょうか?
ヘッダ情報をsw.WriteLineした後に、StreamWriterを閉じずに素直に各Excelデータを行ごとにsw.WriteLineした方が効率的です。
実は、Excelデータ書き込み時にストリームの書き込み位置をいじっているのが文字化けの原因かも?

投稿2019/09/18 05:42

編集2019/09/18 05:52
kenshirou

総合スコア772

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mia1620

2019/09/18 06:25

ありがとうございます。 ループ部分は写し漏れです。すみません。おっしゃる通りループで書き込みをしています。 確かにヘッダ情報を書いた後に一度に書き込んだ方がスマートですね。 そうすることにします。行ごとにsw.WriteLineしたら改行の件は解決しました。ありがとうございます。 文字化けなのですが、ストリームの書き込み位置を変えない状態でも発生してしまいました。生成ファイルをメモ帳で開くと、以下のように正常です。 Name,,ID みゆき,,123.3 要,,11.2 ikeda,,22.5 Excelで開いたときのみなのですが、わかりますでしょうか?
kenshirou

2019/09/18 07:07

文字化けの件ですが、CSV書き込み時のエンコードをShift_JISにするのが一番手っ取り早いです。 FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None); StreamWriter sw = new StreamWriter(fs, Encoding.GetEncoding("Shift_JIS"));
mia1620

2019/09/18 07:29

エンコードをShift_JISにすると文字化け解決しました。 ソースまで教えていただきありがとうございました。
guest

0

Excel のメニューで「開く」を使って CSV ファイルを開くときは、

  • UTF-8を示す BOM 付き(ファイルの先頭3バイトが EF BB BF である)であれば UTF-8 として
  • それ以外であれば Shift-JIS として

読み込もうとします。

Excel に食わせるなら Shift-JIS が第1候補で、第2候補は BOM 付き UTF-8 となります。
※他のアプリで使う場合に、BOM 付き UTF-8 だと問題が起きる可能性はあります

投稿2019/09/18 07:30

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mia1620

2019/09/18 07:35

ありがとうございます。 BOM付UTF-8というものを初めて知りました。他のアプリを使う時には問題が起きる可能性があるんですね。教えていただき、ありがとうございます。
tacsheaven

2019/09/18 07:47 編集

Unicodeはもともと1文字を複数バイトで表す前提のコード体系です。ですが複数バイトが並ぶ場合、システムによってはどちらを先頭バイトとするかが異なる(AA BB とあった場合に、これを 0xAABB (ビッグエンディアン)と見るのか、0xBBAA (リトルエンディアン)と見るのか)ため、それを区別できるように先頭に識別用のマークを埋め込むことが可能なようになっています。これが BOM(Byte Order Mark)です。 UTF-8 は1文字を可変バイトで表しますが、その際には先頭から順に処理することが決まっていますので、BOM は必要ではありません。ですが他と合わせることと、UTF-8 であることを明示できるように BOMが用意されています。 BOM はバイトオーダーを判定する以外には無視しなくてはならない(実データとしてはならない)のですが、作りの悪いアプリだとそうしてくれないことがあるのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問