4

コンテンツに影響を与えることができない Excel ファイルを受け取りました。「á」や「é」などの Unicode 文字が含まれています。

私のコードは変更されていませんが、Eclipse Juno から LiClipse に一緒に移行して、別の python パッケージ (2.5 から 2.6) に移行しました。原則として、私が使用している特定のパッケージには、win32com パッケージで動作するバージョンがあります。

Excel ファイルを読み取ると、str() を使用して抽出して文字列に変換するときにコードがクラッシュします。コンソール出力は次のとおりです。

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 89: ordinal not in range(128)

より具体的には、次のことを実行します。

エクセルを読む:

  xlApp = Dispatch("Excel.Application")

  excel = xlApp.Workbooks.Open(excel_location)

内部ループで、セルの値を抽出します。

cell_value = self.excel.ActiveSheet.Cells(excel_line + 1, excel_column + 1)

最後に、cell_value を str に変換しようとすると、クラッシュします。

print str(cell_value)

Excel にアクセスして非 ASCII 文字を削除すると、すべてがスムーズに機能します。このエンコードの提案を試しました。私がグーグルで検索した他の解決策は、ファイルを特定の形式で保存することを提案していますが、それはできません。

私を困惑させているのは、以前は同じ入力 Excel でコードが機能していたのに、この LiClipse と 2.6 Python への変更がすべてを殺してしまったことです。

どうすれば進歩できますか?

4

4 に答える 4

3

これは、Python 2.x で UTF-8 でエンコードされた Unicode データを扱う場合によくある問題です。この処理は 2.4 と 2.7 の間でいくつかの場所で変更されているため、突然エラーが発生しても驚くことではありません。

エラーの原因は次のprintとおりです。 Python 2.x では、print端末がサポートするエンコーディングを想定しようとしません。保存を再生するだけで、それがサポートされている唯一の文字セットであると想定しますascii(つまり、0 から 127 までの文字は問題なく、それ以外はすべてエラーになります)。

次に、a を文字列に変換しCOMObjectます。strPython 2.x に関する限り、単なる一連のバイト (値 0 から 255) です。エンコーディングはありません。

この 2 つを組み合わせると、問題が発生します。Python が印刷するとき、入力 (文字列) を検証しようとし、突然 UTF-8 でエンコードされた文字を見つけます (UTF-8 は\xe1、次のバイトが何らかの形で特別であることをデコーダーに伝えるこれらの奇妙なマーカーを追加します;詳細については Wikipedia を確認してください)。 )。

そのとき、asciiエンコーダーは次のように言います。

つまり、この値を操作したり、比較したりできますが、それはできませんprint。印刷の問題の簡単な修正方法は次のとおりです。

s = str(cell_value) # Convert COM -> UTF-8 encoded string
print repr(s) # repr() converts anything to ascii

端末が UTF-8 をサポートしている場合は、Python にそのことを伝える必要があります。

import sys
import codecs

sys.stdout = codecs.getwriter('utf8')(sys.stdout)

sys.stdout.encodingまた、Python が現在出力エンコーディングをどのように考えているか、またはどのようにすべきかを示す も参照する必要があります。Python 2 が (最新の Linux ディストリビューションのように) 適切に構成されている場合、出力用の正しいコーデックが自動的に使用されます。

関連している:

于 2015-04-21T11:51:15.837 に答える
2

ここで説明されているのはハックです。長期的な解決策として使用しないでください。コメントを見ると、端末がクラッシュする可能性があります。

最後に、@ Huan-YuTseng が提供した提案に助けられた解決策を見つけました。おそらく、他の人が提供した解決策は、他のコンテキストでは機能しますが、このコンテキストでは機能しない可能性があります。

それで、何が起こったのかというと、Eclipse Juno バージョン (このコンピューターでは達成できない Java アップグレードが必要なため Pydev が動作を停止したため) から LiClipse ダイレクト パッケージ (ダウンロードした Eclipse バージョンをアップグレードしていません) に移行したことです。

デフォルトでは、私の LiClipse バージョン (1.4.0.201502042042) では、コンソール出力はデフォルトで utf-8 ではありません。そのため、LiClipse またはコードを使用して出力を変更する必要がありました。幸いなことに、私を助けた同様の問題に関連する別の質問がありました。詳細はこちらで確認できますが、基本的には、コードの先頭に次のコードを含める必要があります。

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

そして、すべてが機能します。@AarongDigulla からの回答には解決策がありますが、実際には最後の解決策です。

ただし、LiClipse が sys.setdefaultencoding ステートメントでエラーを出していると言わなければなりません。実行中に問題が発生することはありません...何が起こっているのかわかりません。そのため、以前にこのソリューションをテストするのをやめました。LiClipse に何か問題があるのか​​もしれません (エラーのあるコードを実行できてしまうのです!)

于 2015-04-22T07:27:31.357 に答える
2

.Cells(row,col)オブジェクトを返しRangeます。おそらく、セルからのテキストが必要です。

cell = xl.ActiveSheet.Cells(1,2).Text

また

cell = xl.ActiveSheet.Range('B1').Text

結果の値は Unicode 文字列になります。ファイルに書き込めるバイト数に変換するには、次のように を使用します.encode(encoding)

bytes = cell.encode('utf8')

以下の例では、次のスプレッドシートを使用しています。

ここに画像の説明を入力

import win32com.client
xl = win32com.client.gencache.EnsureDispatch('Excel.Application')
xl.Workbooks.Open(r'book1.xlsx')
cell = xl.ActiveSheet.Cells(1,2)
cell_value = cell.Text
print repr(cell)
print repr(cell_value)
print cell_value

出力 (注: 中国語は、コンソール/IDE が文字をサポートしている場合にのみ出力されます):

<win32com.gen_py.Microsoft Excel 14.0 Object Library.Range instance at 0x129909424>
u'\u4e2d\u56fd\u4eba'
中国人
于 2015-04-21T15:53:42.187 に答える