【问题标题】:u2013 error with openpyxl - python 2.7openpyxl的u2013错误-python 2.7
【发布时间】:2018-09-27 15:56:41
【问题描述】:

我正在使用 python2.7。我不能使用 python 3。我写这个是为了将一个 excel 电子表格转换为 csv。它为“u2013”​​引发错误,这是一个“破折号”字符。在 perl - 您可以使用 open 命令加载 unicode 文件,但我不知道如何在 python 中执行此操作。

#!/home/casper/python/core/2.7.14/exec/bin/python2.7
# -*- coding: utf-8 -*-
import openpyxl
import csv

wb = openpyxl.load_workbook('RiskLimitSnapshot.xlsx')
sh = wb.get_active_sheet()
with open('goodRiskLimitSnapshot.csv', 'wb') as f: 
    c = csv.writer(f)
    for r in sh.rows:
        c.writerow([cell.value for cell in r])

错误:

Traceback (most recent call last):
  File "/home/casper/pyExceltoCSV", line 16, in <module>
    c.writerow([cell.value for cell in r])
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2013' in position 74: ordinal not in range(128)

我将脚本更改为使用 io.open:

wb = openpyxl.load_workbook('DailyETRiskLimitSnapshot.xlsx' ,   data_only=True)
sh = wb.get_active_sheet()
    with io.open('goodDailyETRiskLimitSnapshot.csv', 'w', encoding='utf8') as f:
    c = csv.writer(f, dialect='excel')
    for r in sh.rows:
        c.writerow([cell.value for cell in r])

但是它抛出了一个不同的错误:

Traceback (most recent call last):
  File "./pyExceltoCVS.py", line 20, in <module>
    c.writerow([cell.value for cell in r])
TypeError: write() argument 1 must be unicode, not str

【问题讨论】:

  • wb = openpyxl.load_workbook('DailyETRiskLimitSnapshot.xlsx',encoding_override="cp1252") 我正在寻找这样的功能 - 在 load_workbook 函数中对 excel 进行编码
  • “我收到一个“u'\u2013'”错误,我认为它是连字符的符号” U+2013 是 EN 的 Unicode 代码点DASH,但我不知道你所说的额外的u 和单引号是什么意思。
  • 编辑了 Borodin - 它在 python 的错误代码中,但可能不应该在标题中。
  • Excel 电子表格中只有一个选项卡 - 一张表中没有多个工作簿。
  • 您的问题不在于读取 - 它工作正常,并且正在加载 unicode。您只需要弄清楚如何将 unicode 写入 csv。为此,请使用 cell.value.decode() 从 str 转到 unicode...

标签: python excel


【解决方案1】:

打开文件进行编码输出的正确方法是使用io 模块:

import io

with io.open('goodRiskLimitSnapshot.csv', 'w', encoding='utf8') as f: 
    c = csv.writer(f)
    for r in sh.rows:
        c.writerow([cell.value for cell in r])

【讨论】:

  • 抛出错误——回溯(最近一次调用最后一次):文件“./pyth_excelCVS.py”,第 20 行,在 c.writerow([cell.value for cell in r] ) TypeError: write() 参数 1 必须是 unicode,而不是 str
【解决方案2】:

你试试?

#!/home/casper/python/core/2.7.14/exec/bin/python2.7
# -*- coding: utf-8 -*-
import openpyxl
import csv

wb = openpyxl.load_workbook('RiskLimitSnapshot.xlsx')
sh = wb.get_active_sheet()
with open('goodRiskLimitSnapshot.csv', 'wb') as f: 
    c = csv.writer(f)
    for r in sh.rows:
        c.writerow(unicode([cell.value for cell in r]))

【讨论】:

    【解决方案3】:

    您是否尝试过使用pandas:

    wb = pd.read_excel('RiskLimitSnapshot.xlsx') #you can specify the sheet name using sheetname argument
    wb.to_csv('goodRiskLimitSnapshot.csv', encoding='utf-8')
    

    您也可以使用codecs 并执行以下操作:

    codecs.open(filename, encoding='utf8')
    

    【讨论】:

    • 我们在已批准的模块列表中有熊猫——从未见过它在使用中,也不知道如何使用它。
    • panda 没有链接到 python3.* 并且这个盒子只有 python2.7
    • @casper 为了清楚起见,您尝试了import codecs,但没有成功?
    • 这是一个高度受控的工作环境(向正在阅读此消息的 InfoSec 人员致以问候)。您不能导入自己的模块或进行自己的配置 - 到 perl 或 python。添加模块的过程很漫长,需要总经理批准。基本上这里的人只是使用已经批准的东西。
    【解决方案4】:

    Python3 通过使用默认编码作为 unicode 使很多事情变得更容易。但是在 Python2 中,你会得到一个默认的 str 和不同的 unicode 表示

    现在考虑en-dash = 的情况,看起来与普通的- 相似但不是。

    让我们启动一个 python 2.7 控制台,看看有什么不同

    >>> val_str = '–'
    >>> val_str
    '\xe2\x80\x93'
    

    以上是en-dash 是如何由str 表示的。而对于unicode

    >>> val_unicode = u'–'
    >>> val_unicode
    u'\u2013'
    

    现在让我们尝试使用不同的组合将这些写入csv 文件

    # -*- coding: utf-8 -*-
    
    import csv
    import io
    
    val_str = '–'
    val_unicode = u'–'
    
    
    def try_writing_csv(filename, data, mode='w', **kwargs):
        try:
            with io.open(filename, mode=mode, **kwargs) as f:
                c = csv.writer(f, dialect='excel')
                c.writerow([data])
        except Exception, ex:
            print("failed to write - " + filename)
    
    
    try_writing_csv("ascii1.csv", val_str)
    try_writing_csv("ascii2.csv", val_str, encoding="utf8")
    try_writing_csv("ascii3.csv", val_str.decode('utf8'), encoding="utf8")
    
    try_writing_csv("unicode1.csv", val_unicode)
    try_writing_csv("unicode2.csv", val_unicode, encoding="utf8")
    try_writing_csv("unicode3.csv", val_unicode.encode('utf8'), encoding="utf8")
    

    现在让我们运行同样的方法

    failed to write - ascii1.csv
    failed to write - ascii2.csv
    failed to write - ascii3.csv
    failed to write - unicode1.csv
    failed to write - unicode2.csv
    failed to write - unicode3.csv
    

    结果是压倒性的,因为所有的方法都失败了。所以我们需要看看它有什么问题。让我们再做一些试验

    try_writing_csv("ascii4.csv", val_str.decode('utf8'), mode="wb")
    try_writing_csv("ascii5.csv", val_str, mode="utf8")
    try_writing_csv("ascii6.csv", val_str.decode('utf8').encode('utf8'), mode="wb")
    
    try_writing_csv("unicode4.csv", val_unicode, mode="wb")
    try_writing_csv("unicode5.csv", val_unicode.encode('utf8'), mode='wb')
    

    现在 out run 会给出一个输出

    failed to write - ascii1.csv
    failed to write - ascii2.csv
    failed to write - ascii3.csv
    failed to write - ascii4.csv
    failed to write - ascii5.csv
    failed to write - unicode1.csv
    failed to write - unicode2.csv
    failed to write - unicode3.csv
    failed to write - unicode4.csv
    

    所以ascii6.csvunicode.csv 实际上是成功的。让我们也检查一下文件

    看起来我们确实对这两个文件都做了正确的处理。所以最后两个有效的语句如下

    try_writing_csv("ascii6.csv", val_str.decode('utf8').encode('utf8'), mode="wb")
    try_writing_csv("unicode5.csv", val_unicode.encode('utf8'), mode='wb')
    

    所以关键的学习

    • 打开文件时不要使用encoding=utf8
    • 使用二进制模式写入文件
    • 如果是str,则decodeutf8,然后编码为utf8
    • 如果是unicode,则encodeutf8

    接下来是解释时间,你可以从下面的 SO 线程中得到它

    2.7 CSV module wants unicode, but doesn't want unicode

    如果您尝试写出 unicode 数据,则必须在将数据传递给csv.writer() 对象之前对数据进行编码csv module examples section 包含的代码可以在编写之前从 Unicode 编码更容易一些。

    【讨论】:

    • 这非常好 - 我仍然需要计算粗略的笔画。我仍然无法让脚本工作。
    • 在打开文件时尝试使用cp1252作为编码
    • 是的 - 我很早就尝试过 windows 编码 - 没有骰子。
    • 如果你能分享文件,我可以试一试
    • @capser,如果你不分享更多细节,你的问题很难解决,而且赏金即将到期
    【解决方案5】:

    Python2 csv 库不支持很好的 unicode。 您是否考虑过使用库 unicodecsvbackports.csv

    干杯!

    【讨论】:

      【解决方案6】:

      该错误告诉您您正在尝试将 python unicode 对象写入文件并且默认 ASCII 编解码器无法对其进行编码。隐式调用编码以将 python 字符串/unicode 对象转换为字节。您应该自己使用所需的编码 - utf-8 在您的情况下:

      更改该行:

      c.writerow([cell.value for cell in r])
      

      到:

      c.writerow([cell.value.encode('utf-8') for cell in r])
      

      在没有明确指定所需编码的情况下,使用默认值,您的 writerow 调用变体可以写为:c.writerow([cell.value.encode('ascii') for cell in r]),当然会引发 UnicodeEncodeError,因为您有 unicode 字符串。

      您可以使用以下代码检查您的默认编码:

      import sys
      sys.getdefaultencoding()
      

      【讨论】:

        猜你喜欢
        • 2013-12-18
        • 2017-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-10
        • 1970-01-01
        相关资源
        最近更新 更多