8

Excel .xls/.xlsx ファイルを読み取り、CSV および Unicode テキストに出力する C# プログラムを作成しました。空白のレコードを削除する別のプログラムを作成しました。これは、各行を で読み取りStreamReader.ReadLine()、文字列を 1 文字ずつ処理し、すべてのコンマ (CSV の場合) またはすべてのタブ (Unicode テキストの場合) が含まれている場合、行を出力に書き込まないことで実現されます。

この問題は、Excel ファイルのセル内に改行 (\x0A) が含まれている場合に発生します。XLS から CSV へのコンバーターを変更して、これらの新しい行を検索し (セルごとに移動するため)、\x0A として書き込みます。通常の行は StreamWriter.WriteLine() を使用するだけです。

この問題は、空白のレコードを削除する別のプログラムで発生します。で読み込むとStreamReader.ReadLine()、定義により、ターミネータではなく、行を含む文字列のみが返されます。埋め込まれた改行は 2 つの別々の行として表示されるため、最終的なファイルに書き込むときに、どちらが完全なレコードで、どちらが埋め込まれた改行であるかはわかりません。

入力のすべてが '\n' として登録されるため、\x0A を読み取れるかどうかさえわかりません。文字ごとに移動することもできますが、これにより、空白行を削除するロジックが破壊されます。

4

5 に答える 5

4

行終端文字を返すように変更StreamReaderすることはできません。また、行終端に使用するものを変更することもできません。

あなたが何をエスケープしているのか、特に「\ x0Aとして書く」という点で、問題について完全にはわかりません。ファイルのサンプルが役立つでしょう。

文字ごとに作業するか、最初にファイル全体をロードしてグローバル置換を行う必要があるようです。

x.Replace("\r\n", "\u0000") // Or some other unused character
 .Replace("\n", "\\x0A") // Or whatever escaping you need
 .Replace("\u0000", "\r\n") // Replace the real line breaks

正規表現を使用してそれを行うことができ、おそらくより効率的であると確信していますが、はるかに理解しやすいと思います:)ただし、グローバルな置換を行う必要があるのは少しハックです-うまくいけば、より多くの情報が得られますより良い解決策を考え出します。

于 2009-03-20T20:12:24.120 に答える
1

基本的に、Excel のハード リターン (Shift + Enter または Alt + Enter、覚えていません) は、CSV を記述するために使用する既定のエンコーディングで \x0A に相当する改行を挿入します。CSV に書き込むときは、StreamWriter.WriteLine() を使用します。これは、行と改行 (\r\n だと思います) を出力します。

CSV は問題なく、Excel が保存する方法とまったく同じです。問題は、それを空白のレコード リムーバーに読み込むときです。改行が埋め込まれたレコードを CRLF として扱う ReadLine() を使用しています。

CSVに変換した後のファイルの例を次に示します...

Reference,Name of Individual or Entity,Type,Name Type,Date of Birth,Place of Birth,Citizenship,Address,Additional Information,Listing Information,Control Date,Committees
1050,"Aziz Salih al-Numan
",Individual,Primary Name,1941 or 1945,An Nasiriyah,Iraqi,,Ba’th Party Regional Command Chairman; Former Governor of Karbala and An Najaf Former Minister of Agriculture and Agrarian Reform (1986-1987),Resolution 1483 (2003),6/27/2003,1518 (Iraq)
1050a,???? ???? ???????,Individual,Original script,1941 or 1945,An Nasiriyah,Iraqi,,Ba’th Party Regional Command Chairman; Former Governor of Karbala and An Najaf Former Minister of Agriculture and Agrarian Reform (1986-1987),Resolution 1483 (2003),6/27/2003,1518 (Iraq)

ご覧のとおり、最初のレコードには al-Numan の後に改行が埋め込まれています。ReadLine() を使用すると、'1050,"Aziz Salih al-Numan' が返され、それを書き出すと、WriteLine() はその行を CRLF で終了します。元の行ターミネータを失います。ReadLine() を再度使用すると、 、「1050a」で始まる行を取得します。

ファイル全体を読み込んで置き換えることはできましたが、後で元に戻す必要がありました。基本的に私がやりたいことは、行末記号を取得して \x0a か CRLF かを判断し、\x0A の場合は、Write() を使用してその終端記号を挿入することです。

于 2009-03-20T20:24:01.347 に答える
0

あなたのコードと、次の解決策を思いついた他のいくつかのコードに感謝します! このページのロジックの一部を使用して作成したコードへのリンクを下部に追加しました。私は名誉あるところに名誉を与えると思った!ありがとう!

以下は、私が必要としたものについての説明です: これを試してみてください。一部の列の中に \r\n がある区切られたファイルと、行末区切り記号として \r\n を使用する必要がありました。SSIS パッケージを使用していくつかのファイルをインポートしようとしましたが、ファイル内の一部のデータが破損しているため、インポートできませんでした。ファイルが 5 GB を超えていたため、大きすぎて開いて手動で修正できませんでした。ストリームがどのように機能するかを理解するために多くのフォーラムを調べて答えを見つけ、ファイル内の各文字を読み取り、追加した定義に基づいて行を吐き出すソリューションにたどり着きました。これはコマンドラインアプリケーションで使用するためのもので、ヘルプ付きです:)。これが他の人に役立つことを願っています。他のどこにも似た解決策は見つかりませんでした。

https://stackoverflow.com/a/12640862/1582188

于 2012-09-28T13:26:10.703 に答える