あなたは説明を求めましたが、いくつかの現象はあなたの助けなしでは説明できません。
(A)Excel 97以降で作成されたXLSファイルの文字列は、可能であればUTF16LEでLatin1でエンコードされます。各文字列には、どちらが使用されたかを示すフラグが付いています。以前のExcelは、ユーザーの「コードページ」に従って文字列をエンコードしていました。いずれの場合も、xlrdはUnicodeオブジェクトを生成します。ファイルのエンコードは、XLSファイルがサードパーティのソフトウェアによって作成された場合にのみ重要です。サードパーティのソフトウェアは、コードページを省略しているか、コードページに依存しています。xlrdドキュメントの前にあるUnicodeセクションを参照してください。
(B)原因不明の現象:
このコード:
bcw = csv.writer(bc,csv.excel,b.encoding)
Python 2.5、2.6、および3.1で次のエラーが発生しますTypeError: expected at most 2 arguments, got 3
。-これは、csv.writerのドキュメントから予想されるものです。ファイルのようなオブジェクトの後に、(1)何もない(2)方言、または(3)1つ以上のフォーマットパラメータが続くことを想定しています。あなたはそれに方言を与えました、そしてcsv.writerにはエンコーディング引数がないので、スプラットします。どのバージョンのPythonを使用していますか?または、実際に実行したスクリプトをコピーして貼り付けませんでしたか?
(C)トレースバックに関する原因不明の現象と、実際の問題のあるデータは次のとおりです。
"the_script.py", line 40, in <module>
this_row.append(str(s.cell_value(row,col)))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xed' in position 5: ordinal not in range(128)
まず、問題のあるコード行に、簡略化されたスクリプトにはなかったstr()があります。実際に実行したスクリプトをコピーして貼り付けませんでしたか?いずれにせよ、一般的にstrを使用するべきではありません。フロートで完全な精度を得ることができません。csvモジュールに変換させてください。
次に、"""値がハングアップしているようです"516-777316"-元のExcelシートのテキストは"516-7773167"(末尾に7が付いています)" ""- -7がどのように最後から失われるかを想像するのは難しいです。問題のあるデータが何であるかを正確に調べるには、次のようなものを使用します。
try:
str_value = str(s.cell_value(row, col))
except:
print "row=%d col=%d cell_value=%r" % (row, col, s.cell_value(row, col))
raise
その%rにより、入力する手間が省けますcell_value=%s ... repr(s.cell_value(row, col))
... repr()は、データの明確な表現を生成します。勉強しなさい。これを使って。
どうやって「516-777316」にたどり着きましたか?
第3に、エラーメッセージは、実際にはオフセット5(つまり6番目の文字)にあるUnicode文字u'\xed'について不平を言っています。U + 00EDはラテン語の小さな文字Iであり、「516-7773167」にはそのようなものはまったくありません。
第4に、エラーの場所は移動するターゲットのようです。解決策の1つについてのコメントで、「エラーはbcw.writerowにあります」と述べています。は?
(D)エラーメッセージが表示される理由(str()を使用):str(a_unicode_object)
Unicodeオブジェクトをstrオブジェクトに変換しようとし、エンコード情報がない場合はasciiを使用しますが、非ASCIIデータがあるため、スプラットします。オブジェクトはutf8でエンコードされたcsvファイルを生成することですが、簡略化されたスクリプトではutf8についてはどこにも言及されていないことに注意してください。
(E) "" "... s.cell(row、col))(s.cell_value)
ドキュメント全体の代わりにegscellがエラーなしで書き込みます。出力は特に望ましくありません(text:u'516-7773167')" ""
これは、csvライターが__str__
Cellオブジェクトのメソッドを呼び出しているために発生します。これにより<type>:<repr(value)>
、デバッグに役立つ可能性がありますが、csvファイルではそれほど優れていません。
(F)Alex Martelliのソリューションは、うまくいくという点で優れています。ただし、xlrdドキュメントのCellクラスのセクションを読む必要があります。セルのタイプは、テキスト、数値、ブール値、日付、エラー、空白、および空です。日付がある場合は、数値ではなく日付としてフォーマットする必要があるため、isinstance()を使用することはできません(とにかく関数呼び出しのオーバーヘッドは必要ない場合があります)...これがCell.ctype
属性Sheet.cell_type()
とSheet.row_types()
メソッドですのためです。
(G)UTF8はUnicodeではありません。UTF16LEはUnicodeではありません。UTF16はUnicodeではありません...そして個々の文字列がUTF16BOMでそれぞれ2バイトを浪費するという考えは、MSでさえ考えるにはあまりにも馬鹿げています:-)
(H)さらに読む(xlrdドキュメントは別として):
http://www.joelonsoftware.com/articles/Unicode.html
http://www.amk.ca/python/howto/unicode