2017-06-02 110 views
0

我正在使用openpyxl導入現有的excel表格並試圖填充一些值並重新保存,但我注意到這樣做時電子表格中現有的Data Validation下拉框會搞砸。即使只是加載電子表格,不做任何其他操作,然後重新保存,也會發生這種情況,所以它似乎是openpyxl的內在特性。電子表格中的數據驗證由某些單元格中的Dropbox組成,這些單元格從大約20列以上的其他單元格中獲取可能值(這是爲公司生成QC報告)。例如,單元格C13具有$ Z $ 6:$ AB $ 6的初始數據有效性「源」,但是在加載並保存Excel表格後,該單元格會錯誤地更改爲$ Z $ 5:$ AB $ 5。奇怪的是,這在所有單元格中並不一致;一些細胞保持在正確的範圍內,而一些細胞卻是五行左右。它看起來像只有行,而不是列。所有包含數據驗證的單元格都會合並,我不確定是否重要。有誰知道爲什麼會發生這種情況,或者如何解決這個問題?沒有太多的代碼來顯示,但這裏是一個負載的一個簡單例子/保存功能,這將導致此問題:openpyxl導致excel中現有的DataValidation丟失

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

提前感謝! Robert

+0

我試過了,但無法重現該問題。你使用的是最新版本的'openpyxl'(目前是2.4.7)嗎? – Xukrao

+0

嗨Xukrao,是的,我正在使用最新版本的openpyxl。在嘗試重新創建問題時,我注意到它有時不會出現在具有示例數據驗證的簡單電子表格中。我重新創建了一個示例電子表格,這個問題確實發生,但我似乎無法在這裏上傳,所以這裏是電子表格的Dropbox鏈接:https://www.dropbox.com/s/sbw07makodkg7oo/DataValidationErrorExample.XLSX?dl = 0您可以看到Test1-3的「DV」行與它們的「行」選項對齊,但在通過openpyxl傳遞此電子表格後,您將看到鏈接混亂。 –

+0

另外,如果Dropbox鏈接不起作用,我可以通過電子郵件發送示例,如果提供了電子郵件地址。謝謝 –

回答

0

這可能是因爲您的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屬性顯示的數據驗證適用的細胞,你可以看到有不同的之間有一些重疊數據驗證。

+0

啊,這是一個有用的.data_validations函數。但是,從輸出中看,數據驗證在openpyxl加載後就已經搞亂了。如果您在Excel中查看原始電子表格,您可以看到鏈接錯誤地將C15與C28連接起來(對其中的每個單元格提供數據驗證),而應該只是C15和C28。如果我能弄清楚爲什麼它正在閱讀這些內容,並在單元格之間放置:這可能是我的問題的根源。我不知道爲什麼它會這樣做,或者如何解決它。再次感謝您的期待。 –

+0

使用來自.data_validations的知識(openpyxl錯誤地將數據驗證單元格範圍(如C12:C25而不是C12,C25)組合起來)能夠提出解決此問題的解決方法。只要兩個不同行中的單元共享相同的數據驗證輸入,就會出現問題。由於我有兩組所有行,因此我複製了我的數據驗證輸入,使其顯示兩次,並將每行連接到唯一的數據驗證範圍。這不是一個完整的解決方案,也不是理想的解決方案,而是暫時解決問題。如果有人知道一個完整的解決方案,那仍然會有幫助。 –

相關問題