“ValueError: 1 is not a valid column name” error when using .save from openpyxl

huangapple go评论137阅读模式
英文:

"ValueError: 1 is not a valid column name" error when using .save from openpyxl

问题

我有一些代码,它打开一个由另一个代码创建的Excel文件。然后对工作表进行一些基本格式设置,然后保存并关闭文件。这段代码之前正常运行,但突然出现了一些与保存函数有关的随机错误。错误消息是"Key Error '1'"和"1 is not a valid column name"。

以下是您的代码:

import openpyxl as opxl
from openpyxl.styles import Font, PatternFill

# ...(省略部分代码)...

output.save(output_path)
output.close

当前的错误是:

File "openpyxl\utils\cell.py:121 in openpyxl.utils.cell.column_index_from_string
KeyError: '1';

ValueError: 1 is not a valid column name

您已经尝试使用不同的文件名保存,但没有成功。如果去掉.save()行,代码可以运行,但不会保存任何结果。任何帮助将不胜感激。这段代码以前是正常工作的。您对创建output.xlsx文件的代码进行了更改,但该文件仍然保持相同的格式,看起来不会导致这个错误。

如果在第一个错误后再次运行代码,您会遇到一个不同的错误,错误消息是"File is not a zip file"。然后,如果在这个错误之后再次运行代码,会出现另一个不同的错误,错误消息是"There is no item named '[Content_Types].xml' in the archive"。

英文:

I have a some code that opens an excel file that I created with another code. It then does some basic formatting to the sheet and then saves and closes. This code was working fine and then randomly I started getting some random errors on the .save function. It says "Key Error '1'" and "1 is not a valid column name"

Below is my code

import openpyxl as opxl
from openpyxl.styles import Font, PatternFill

chime_low = 60
chime_high = 66
adj_low = -3
adj_high = 3
red_fill = PatternFill(start_color='FFFF0000', end_color='FFFF0000', fill_type='solid')
green_fill = PatternFill(start_color='0000FF00', end_color='0000FF00', fill_type='solid')

output_path = 'output.xlsx'
output = opxl.load_workbook(filename= output_path)
output_sheet = output.active
max_row = output_sheet.max_row
max_column = output_sheet.max_column

a1 = output_sheet['A1']
a1.font = Font(bold=True)
a1.value = 'Chime ID'

v_centerAlignment = opxl.styles.Alignment(
        horizontal="center", vertical="center", wrapText=True
    )

for col in output_sheet.iter_cols(min_row=1, min_col=1, max_row = max_row, max_col = max_column):
    for cell in col:
        cell_str = str(cell)
        col_let = cell_str[-3]
        cell.alignment = v_centerAlignment
        output_sheet.column_dimensions[f'{col_let}'].width = 20
      
        
for col in output_sheet.iter_cols(min_row=2, min_col=3, max_row = max_row, max_col = 3):
    for cell in col :
        if chime_low <= cell.value <= chime_high:
            cell.fill = green_fill
        else:
            cell.fill = red_fill
            
for col in output_sheet.iter_cols(min_row=2, min_col=4, max_row = max_row, max_col = 4):
    for cell in col :
        if adj_low <= cell.value <= adj_high:
            cell.fill = green_fill
        else:
            cell.fill = red_fill            
            
output.save(output_path)

output.close

And here is the current error

Formatting.py', wdir='C:/Users/LZMYKK/Documents/Python Scripts/Chime Automation')
Traceback (most recent call last):

  File openpyxl\utils\cell.py:121 in openpyxl.utils.cell.column_index_from_string

KeyError: '1'


During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
    exec(code, globals, locals)

  File c:\users\lzmykk\documents\python scripts\chime automation\chime post processing excel formatting.py:49
    output.save(output_path)

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\openpyxl\workbook\workbook.py:407 in save
    save_workbook(self, filename)

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\openpyxl\writer\excel.py:293 in save_workbook
    writer.save()

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\openpyxl\writer\excel.py:275 in save
    self.write_data()

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\openpyxl\writer\excel.py:75 in write_data
    self._write_worksheets()

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\openpyxl\writer\excel.py:215 in _write_worksheets
    self.write_worksheet(ws)

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\openpyxl\writer\excel.py:200 in write_worksheet
    writer.write()

  File openpyxl\worksheet\_writer.py:358 in openpyxl.worksheet._writer.WorksheetWriter.write

  File openpyxl\worksheet\_writer.py:103 in openpyxl.worksheet._writer.WorksheetWriter.write_top

  File openpyxl\worksheet\_writer.py:87 in openpyxl.worksheet._writer.WorksheetWriter.write_cols

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\openpyxl\worksheet\dimensions.py:233 in to_tree
    for col in sorted(self.values(), key=sorter):

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\openpyxl\worksheet\dimensions.py:227 in sorter
    value.reindex()

  File ~\AppData\Local\miniconda3\envs\spyder-env\lib\site-packages\openpyxl\worksheet\dimensions.py:176 in reindex
    self.min = self.max = column_index_from_string(self.index)

  File openpyxl\utils\cell.py:123 in openpyxl.utils.cell.column_index_from_string

ValueError: 1 is not a valid column name

I tried using a different filename for saving and it did not work. I also got rid of the .save() line and the code runs but of course does not actually save any of my results. Any help would be appreciated. This code completely worked before. I did make changes to the code that creates the output.xlsx file, but that file is all still in the same format and seems like it wouldn't cause this error.

If I run the code a second time after the first error I get a different error that says "File is not a zip file" and then if I run it again after this error, I get another different error that says "There is no item named '[Content_Types].xml' in the archive"

答案1

得分: 2

以下是代码部分的中文翻译:

我认为您在这段代码中存在问题,这可能导致"Key Error '1'"和"1不是有效的列名"错误:

# for col in output_sheet.iter_cols(min_row=1, min_col=1, max_row=max_row, max_col=max_column):
for col in output_sheet.iter_cols(min_row=1, min_col=1, max_row=1, max_col=max_column):
    for cell in col:
        # cell_str = str(cell)
        # col_let = cell_str[-3]
        col_let = cell.column_letter
        cell.alignment = v_centerAlignment
        output_sheet.column_dimensions[f'{col_let}'].width = 20

您从cell_str[-3]中确定列字母,这对于行1到9的单元格(如'A1','A2','A3')可以正常工作,返回'A'。但是当您达到行'A10'及更高行(直到'A19')时,返回值现在是1(直到'A20',它将变为2,依此类推)。然后,您会得到一个整数作为列字母,当您运行以下行时:

output_sheet.column_dimensions[f'{col_let}'].width = 20

您将会有一个损坏的工作表。

要获取列字母,请使用:

cell.column_letter

正如CC指出的那样,您不需要遍历所有已使用的单元格,只需遍历第一行。迭代应该是max_row=1

for col in output_sheet.iter_cols(min_row=1, min_col=1, max_row=1, max_col=max_column):

如果这样做,您的错误将永远不会发生,但是获取列字母的方法应该进行更改。

另外,您不需要以下这一行:

output.close

对于您的代码来说,它没有任何作用。

英文:

I believe you have an issue with this bit of code which would cause a "Key Error '1'" and "1 is not a valid column name" error;

# for col in output_sheet.iter_cols(min_row=1, min_col=1, max_row=max_row, max_col=max_column):
for col in output_sheet.iter_cols(min_row=1, min_col=1, max_row=1, max_col=max_column):
    for cell in col:
        # cell_str = str(cell)
        # col_let = cell_str[-3]
        col_let = cell.column_letter
        cell.alignment = v_centerAlignment
        output_sheet.column_dimensions[f'{col_let}'].width = 20

You are determining column letter from cell_str[-3] which would work for cells in rows 1 to 9, like 'A1', 'A2', 'A3' returning 'A'. However when you reach row 'A10' and up [to 'A19'] the return is now 1 (until 'A20' where it will be 2 and so on). So then you have a column letter which is an integer and when you run this line

output_sheet.column_dimensions[f'{col_let}'].width = 20

you have a corrupted sheet. <br><br>
To get the column letter use

cell.column_letter

As CC points out; you dont need to loop thru all the used cells anyway, only the first row. The iteration should be max_row=1;

for col in output_sheet.iter_cols(min_row=1, min_col=1, max_row=1, max_col=max_column):

If this was done your error would never have occurred but your method to obtain the column letter should be changed either way.<br>
<br>
See edits to your code sample above.<br>
<br>
Also you do not need the line

output.close

for your code it does nothing.

huangapple
  • 本文由 发表于 2023年3月7日 01:31:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75654008.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定