Python - 自动调整excel文件列的宽度

Adi*_*tya 12 python excel openpyxl

新手 - 我有一个Python脚本,根据指定的值调整excel文件的不同列的宽度:

import openpyxl
from string import ascii_uppercase

newFile = "D:\Excel Files\abc.xlsx"

wb = openpyxl.load_workbook(filename = newFile)        
worksheet = wb.active

for column in ascii_uppercase:
    if (column=='A'):
        worksheet.column_dimensions[column].width = 30
    elif (column=='B'):
        worksheet.column_dimensions[column].width = 40            
    elif (column=='G'):
        worksheet.column_dimensions[column].width = 45            
    else:
        worksheet.column_dimensions[column].width = 15

wb.save(newFile)
Run Code Online (Sandbox Code Playgroud)

是否有任何方法可以将每列的宽度调整到最佳值,而无需为不同的列明确指定(意味着,不使用此" if-elif-elif -......- elif-else " 结构体)?谢谢!

old*_*sea 36

for col in worksheet.columns:
     max_length = 0
     column = col[0].column # Get the column name
# Since Openpyxl 2.6, the column name is  ".column_letter" as .column became the column number (1-based) 
     for cell in col:
         try: # Necessary to avoid error on empty cells
             if len(str(cell.value)) > max_length:
                 max_length = len(cell.value)
         except:
             pass
     adjusted_width = (max_length + 2) * 1.2
     worksheet.column_dimensions[column].width = adjusted_width
Run Code Online (Sandbox Code Playgroud)

这可能会更整洁,但它确实起作用.您将需要根据您在查看时使用的字体的好处来调整adjust_width值.如果你使用一个monotype你可以得到它精确但它不是一对一的相关性,所以你仍然需要调整一点.

如果你想获得没有monotype的花哨和精确,你可以按宽度排序字母,并为每个宽度分配一个浮动值,然后你加起来.这将需要第三个循环解析单元格值中的每个字符并总结每列的结果,并且可能是按宽度排序字符的字典,如果你这样做可能有点过分但很酷.

编辑:实际上似乎有一种更好的方法来测量文本的视觉大小:个人链接我更喜欢matplotlib技术.

希望我能帮忙,我的第一个stackoverflow答案=)

  • 我认为这里存在一个错误,它阻止了对数字单元格值的正确操作。在第 8 行中,我认为应该是 `max_length = len(str(cell.value))`,而不是 `max_length = len(cell.value)` (2认同)

Man*_*l G 16

从 openpyxl 3.0.0 开始更新版本(使用 .columns 失败并显示TypeError: expected <class 'str'>

for column_cells in ws.columns:
    length = max(len(as_text(cell.value)) for cell in column_cells)
    ws.column_dimensions[column_cells[0].column_letter].width = length
Run Code Online (Sandbox Code Playgroud)

  • 这可行,但我必须用 str() 替换 as_text() (5认同)
  • 按照@virako的建议添加未合并单元格的过滤器 `for column_cells in ws.columns:` `unmerged_cells = list(filter(lambda cell_to_check: cell_to_check.coordinate not in ws.merged_cells, column_cells))` `length = max(len( str(cell.value)) 对于 unmerged_cells 中的单元格)` `ws.column_dimensions[unmerged_cells[0].column_letter].width = length * 1.2` (3认同)
  • @DušanAtanackovic 很高兴听到。我已将其作为 github 要点,以便于阅读 - https://gist.github.com/arvsr1988/4468e7f9bb9c5f3aa514eea6a14804b6 (2认同)

Cor*_*vax 8

使用最新的 openpyxl 你可以使用这个:

from openpyxl.utils import get_column_letter
for idx, col in enumerate(worksheet.columns, 1):
    worksheet.column_dimensions[get_column_letter(idx)].auto_size = True
Run Code Online (Sandbox Code Playgroud)

  • 不为我工作 (4认同)
  • 这似乎根本没有做任何事情;列与之前相同;另请参阅[这个问题](/sf/ask/4217382361/)的第一条评论(“bestFit”似乎是“auto_size”的别名)。 (3认同)

小智 5

根据上面的评论并添加这篇文章openpyxl-调整列宽度大小。我成功了,但答案应该是:

from openpyxl.utils import get_column_letter

for col in ws.columns:
    max_length = 0
    column = get_column_letter(col[0].column)  # Get the column name
    # Since Openpyxl 2.6, the column name is  ".column_letter" as .column became the column number (1-based)
    for cell in col:
        try:  # Necessary to avoid error on empty cells
            if len(str(cell.value)) > max_length:
                max_length = len(cell.value)
        except:
            pass
    adjusted_width = (max_length + 2) * 1.2
    ws.column_dimensions[column].width = adjusted_width
Run Code Online (Sandbox Code Playgroud)

我正在使用 openpyxl =“^3.0.5”