openpyxl导入时请不要将文本视为数字

6
有许多关于如何阻止Excel将文本解释为数字,或者如何使用openpyxl输出数字格式的问题,但我没有看到任何解决此问题的方法:
有人给了我一个Excel电子表格,所以我并没有创建它。当我用Excel打开文件时,我有一些值,比如“5E12”(克隆号码,如果有人在意),看起来显示正确,但每个值旁边都有一个小绿箭头警告我“这似乎是作为文本存储的数字”。然后Excel会问我是否要将其转换为数字,如果我选择是,我就会得到5000000000000,然后自动转换为科学计数法,并再次显示5E12,只有这次文本输出会显示带有零的完整数字。请注意,在转换之前,即使对于Excel而言,这确实是文本,我也只是被警告/提供转换。
因此,当使用openpyxl(从openpyxl.reader.excel导入load_workbook)读取此文件时,“5E12”会自动转换为5000000000000。我认为openpyxl做出了与Excel相同的假设,只是转换发生在没有我的提示或输入的情况下。
如何防止这种情况发生?我不想让看起来像“数字存储为文本”的文本转换为数字。除非我说了算,它们就是文本。
到目前为止,我找到的唯一解决方案是在每个单元格前面添加单引号,但这不是理想的解决方案,因为这是手动劳动而不是程序化的解决方案。此外,解决方案需要通用,因为我不总是知道这个问题可能出现在哪里(我每天读取数百万行数据,所以我不想手动处理任何东西)。
我认为这是openpyxl的问题。从2011年初开始就有一个谷歌小组讨论提到了这个问题,但假设它太罕见了而无关紧要。https://groups.google.com/forum/?fromgroups=#!topic/openpyxl-users/HZfpShMp8Tk 那么,有什么建议吗?

你是否需要对XLSX文件进行写入操作,而不仅仅是读取?如果不需要,你可以考虑使用xlrd,它可以读取XLS和XLSX文件,并且在保留数据类型方面更加出色。 - John Y
@John 谢谢 - 这正是我所需要的。自从我开始这个项目以来,xlrd已经有了很大的改进,所以即使这并没有回答我的实际问题,它确实解决了我的问题,可以放弃openpyxl并切换到xlrd。(编辑:它确实回答了我的问题“如何防止这种情况发生”,只是无法解决如何在openpyxl中实现这一点,如果还有其他人想知道的话。) - Dannid
1个回答

6
如果您想再次使用openpyxl(无论出于何种原因),以下更改工作表读取程序即可将字符串保留为字符串:

diff --git a/openpyxl/reader/worksheet.py b/openpyxl/reader/worksheet.py

--- a/openpyxl/reader/worksheet.py
+++ b/openpyxl/reader/worksheet.py
@@ -134,8 +134,10 @@
             data_type = element.get('t', 'n')
             if data_type == Cell.TYPE_STRING:
                 value = string_table.get(int(value))
-
-            ws.cell(coordinate).value = value
+                ws.cell(coordinate).set_value_explicit(value=value,
+                                                data_type=Cell.TYPE_STRING)
+            else:
+                ws.cell(coordinate).value = value

         # to avoid memory exhaustion, clear the item after use
         element.clear()
Cell.value 是一个属性,赋值调用Cell._set_value,然后执行Cell.bind_value。根据该方法的文档:“给定一个值,推断类型和显示选项”。因为值的类型在 XML 文件中,应该使用它们(这里仅针对字符串)而不是做一些“聪明”的事情。

从代码中可以看出,已经存在了判断是否为字符串的测试。


谢谢,xlrd对我来说运行正常,但是我很高兴也看到了openpyxl的解决方案。如果有机会的话,我会测试它并留下我的反馈。 - Dannid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接