【问题标题】:openpyxl causing loss of existing DataValidation in excelopenpyxl 导致 excel 中现有 DataValidation 丢失
【发布时间】:2017-06-02 21:55:13
【问题描述】:

我正在使用 openpyxl 导入现有的 excel 工作表并尝试填写一些值并重新保存,但我注意到电子表格中现有的数据验证下拉框在这样做时会变得混乱。即使只是加载电子表格,不执行其他操作,然后重新保存,也会发生这种情况,因此它似乎是 openpyxl 固有的。电子表格中的数据验证由某些单元格中的下拉框组成,这些下拉框从大约 20 列的一组其他单元格中获取可能的值(这是为公司生成 QC 报告)。例如,单元格 C13 的初始数据验证“源”为 $Z$6:$AB$6,但在加载并保存 Excel 工作表后,该单元格错误地更改为 $Z$5:$AB$5。奇怪的是,这在所有单元格中并不一致。一些单元格保持在正确的范围内,而一些单元格则关闭了五行左右。看起来它只是按行关闭,而不是按列关闭。所有具有数据验证的单元格都已合并,我不确定这是否重要。有谁知道为什么会发生这种情况,或者如何解决?没有太多代码可以展示,但这里有一个会导致此问题的加载/保存函数的简单示例:

    wb = load_workbook(filename='myspreadsheet.xlsx')
    wb.save('myspreadsheet.xlsx')

提前致谢! 罗伯特

【问题讨论】:

  • 我试过但无法重现该问题。你用的是最新版的openpyxl(目前是2.4.7)吗?
  • 嗨 Xukrao,是的,我正在使用最新版本的 openpyxl。在尝试使用示例数据验证重新创建问题时,我确实注意到它有时不会出现在简单的电子表格中。我重新创建了一个确实发生此问题的示例电子表格,但我似乎无法在此处上传,所以这里是电子表格的保管箱链接:dropbox.com/s/sbw07makodkg7oo/… 您可以看到 Test1-3 的“DV”行与他们的对齐“行”选项,但通过 openpyxl 传递此电子表格后,您会看到链接混乱。
  • 或者,如果保管箱链接不起作用,如果提供了电子邮件地址,我可以通过电子邮件发送示例。谢谢

标签: python excel python-2.7 python-3.x openpyxl


【解决方案1】:

可能是您的 Excel 工作表具有为重叠单元格范围定义的数据验证,从而导致 openpxyl 和/或 excel 混淆。

使用此代码时:

wb = load_workbook(filename='DataValidationErrorExample.XLSX')
ws = wb.worksheets[0]
print(ws.data_validations)

我明白了:

<openpyxl.worksheet.datavalidation.DataValidationList object>
Parameters:
disablePrompts=None, xWindow=None, yWindow=None, count=10, dataValidation=[<openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='list', errorStyle=None, imeMode=None, operator=None, sqref='C15:C28 D15:D28 E15:E28 F15:F28 G15:G28 H15:H28 I15 J15 K15', formula1='$Z$12:$AB$12', formula2=None, <openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='list', errorStyle=None, imeMode=None, operator=None, sqref='I12 J12 K12', formula1='$Z$5:$AC$5', formula2=None, <openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='list', errorStyle=None, imeMode=None, operator=None, sqref='C13:C26 D13:D26 E13:E26 F13:F26 G13:G26 H13:H26 I13 J13 K13', formula1='$Z$6:$AB$6', formula2=None, <openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='list', errorStyle=None, imeMode=None, operator=None, sqref='C12:C25 D12:D25 E12:E25 F12:F25 G12:G25 H12:H25', formula1='$Z$5:$AB$5', formula2=None, <openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='list', errorStyle=None, imeMode=None, operator=None, sqref='G8', formula1='$Z$8:$AB$8', formula2=None, <openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='list', errorStyle=None, imeMode=None, operator=None, sqref='C16:C29 D16:D29 E16:E29 F16:F29 G16:G29 H16:H29 I16 J16 K16', formula1='$Z$9:$AA$9', formula2=None, <openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='list', errorStyle=None, imeMode=None, operator=None, sqref='C17:C30 D17:D30 E17:E30 F17:F30 G17:G30 H17:H30 I17 J17 K17', formula1='$Z$10:$AC$10', formula2=None, <openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='list', errorStyle=None, imeMode=None, operator=None, sqref='C14:C27 D14:D27 E14:E27 F14:F27 G14:G27 H14:H27 I14 J14 K14', formula1='$Z$11:$AA$11', formula2=None, <openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='date', errorStyle=None, imeMode=None, operator=None, sqref='C8 D8', formula1='41275', formula2='43101', <openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
showErrorMessage=True, showDropDown=None, showInputMessage=True, allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None, type='list', errorStyle=None, imeMode=None, operator=None, sqref='J8 K8', formula1='$Z$4:$AA$4', formula2=None]

sqref 属性显示数据验证适用于哪些单元格,并且您可以看到不同数据验证之间存在一些重叠。

【讨论】:

  • 啊,这是 .data_validations 的一个有用功能。但是,从该输出来看,数据验证似乎在被 openpyxl 加载后就已经搞砸了。如果您查看 excel 中的原始电子表格,您会发现链接错误地将 C15 和 C28 连接起来(对中间的每个单元格进行数据验证),而它应该只是 C15 和 C28。如果我能弄清楚为什么它会读取这些内容并在单元格之间放置一个 : ,那可能就是我的问题的根源。我不确定它为什么会这样做或如何解决它。再次感谢您的关注。
  • 使用来自 .data_validations 的知识(openpyxl 错误地组合了数据验证单元格范围,例如 C12:C25 而不是 C12、C25)我能够想出解决此问题的方法。每当两个不同行中的单元格共享相同的数据验证输入时,就会出现问题。由于我对所有内容都有两组行,因此我复制了我的数据验证输入,使其出现两次,并将每一行链接到一个唯一的数据验证范围。这不是一个完整的解决方案,也不理想,但会暂时解决问题。如果有人知道完整的解决方案,那仍然会有所帮助。
猜你喜欢
  • 2020-11-22
  • 2014-05-31
  • 1970-01-01
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
  • 2020-04-12
相关资源
最近更新 更多