openpyxl - 调整列宽大小

Sat*_*ish 54 python openpyxl

我有以下脚本将CSV文件转换为XLSX文件,但我的列大小非常窄.每次我用鼠标拖动它们来读取数据.有人知道如何设置列宽openpyxl吗?

这是我正在使用的代码.

#!/usr/bin/python2.6
import csv
from openpyxl import Workbook
from openpyxl.cell import get_column_letter

f = open('users_info_cvs.txt', "rU")

csv.register_dialect('colons', delimiter=':')

reader = csv.reader(f, dialect='colons')

wb = Workbook()
dest_filename = r"account_info.xlsx"

ws = wb.worksheets[0]
ws.title = "Users Account Information"

for row_index, row in enumerate(reader):
    for column_index, cell in enumerate(row):
        column_letter = get_column_letter((column_index + 1))
        ws.cell('%s%s'%(column_letter, (row_index + 1))).value = cell

wb.save(filename = dest_filename)
Run Code Online (Sandbox Code Playgroud)

Buf*_*fke 67

您可以估计(或使用单宽度字体)来实现此目的.我们假设数据是一个嵌套数组,如[['a1','a2'],['b1','b2']]

我们可以获得每列中的最大字符数.然后将宽度设置为.宽度恰好是等宽字体的宽度(如果不至少更改其他样式).即使你使用可变宽度字体,这也是一个不错的估计.这不适用于公式.

column_widths = []
for row in data:
    for i, cell in enumerate(row):
        if len(column_widths) > i:
            if len(cell) > column_widths[i]:
                column_widths[i] = len(cell)
        else:
            column_widths += [len(cell)]

for i, column_width in enumerate(column_widths):
    worksheet.column_dimensions[get_column_letter(i+1)].width = column_width
Run Code Online (Sandbox Code Playgroud)

有点黑客但你的报告会更具可读性.

  • 当我将 int 作为单元格值时,这会遇到错误,因为 int 没有 len 属性,有没有办法避免这种情况?谢谢! (2认同)

vel*_*lis 33

我对Bufke答案的变化.避免对数组进行一些分支并忽略空单元格/列.

现在修复了非字符串单元格值.

ws = your current worksheet
dims = {}
for row in ws.rows:
    for cell in row:
        if cell.value:
            dims[cell.column] = max((dims.get(cell.column, 0), len(str(cell.value))))    
for col, value in dims.items():
    ws.column_dimensions[col].width = value
Run Code Online (Sandbox Code Playgroud)

  • 第 6 行可以改进为使用列字母: dims[cell.column_letter] = max((dims.get(cell.column_letter, 0), len(str(cell.value)))) (3认同)

小智 29

甚至更多pythonic方式来设置至少在openpyxl版本2.4.0中工作的所有列的宽度:

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

as_text函数应该是将值转换为适当长度字符串的东西,就像Python 3一样:

def as_text(value):
    if value is None:
        return ""
    return str(value)
Run Code Online (Sandbox Code Playgroud)

  • `def as_text(value):如果值不是则返回str(value)否则为"" (4认同)
  • @thorhunter`len(cell.value或“”)`,不需要额外的功能 (3认同)
  • @IrinaVelikopolskaya如果cell.value没有实现__len__,则会抛出异常(例如int或NoneType) (2认同)
  • @IrinaVelikopolskaya 日期时间是另一个出现异常的例子。as_text 函数似乎最适合我。 (2认同)
  • `length = max(map(lambda cell: len(str(cell.value)) if cell.value else 0, column_cells))` - 对我来说更好,Python 清晰且简短 (2认同)
  • 注意,在openpyxl 2.6中,此代码将因TypeError:期望的<class'str'>`而崩溃。现在必须指定一列名称,即`ws.column_dimensions [openpyxl.utils.get_column_letter(column_cells [0] .column)]。width = length'。请参见https://bitbucket.org/openpyxl/openpyxl/issues/尝试更改时1240 / typeerror引发 (2认同)

小智 13

使用 openpyxl 3.0.3 修改列的最佳方法是使用DimensionHolder对象,这是一个将每一列映射到ColumnDimension对象的字典。ColumnDimension 可以获得bestFitauto_size(它是 bestFit 的别名)和width 等参数。就我个人而言,auto_size 没有按预期工作,我不得不使用 width 并发现该列的最佳宽度是len(cell_value) * 1.23.

为了获得每个单元格的值,有必要遍历每个单元格,但我个人没有使用它,因为在我的项目中我只需要编写工作表,所以我直接在我的数据上获得了每列中最长的字符串。

下面的示例仅显示了如何修改列尺寸:

import openpyxl
from openpyxl.worksheet.dimensions import ColumnDimension, DimensionHolder
from openpyxl.utils import get_column_letter

wb = openpyxl.load_workbook("Example.xslx")
ws = wb["Sheet1"]

dim_holder = DimensionHolder(worksheet=ws)

for col in range(ws.min_column, ws.max_column + 1):
    dim_holder[get_column_letter(col)] = ColumnDimension(ws, min=col, max=col, width=20)

ws.column_dimensions = dim_holder
Run Code Online (Sandbox Code Playgroud)


sha*_*yst 9

对上述接受的答案略有改进,我认为它更像 Pythonic(请求宽恕比请求许可更好)

column_widths = []
for row in workSheet.iter_rows():
    for i, cell in enumerate(row):
        try:
            column_widths[i] = max(column_widths[i], len(str(cell.value)))
        except IndexError:
            column_widths.append(len(str(cell.value)))

for i, column_width in enumerate(column_widths):
    workSheet.column_dimensions[get_column_letter(i + 1)].width = column_width
Run Code Online (Sandbox Code Playgroud)

  • 哇那是4年前的事了。尽管我进行了编辑以修复,但您是正确的。刚刚向字符串添加了强制转换。 (2认同)

小智 9

我们可以将数字转换为 ASCII 值并将其传递给 column_dimension 参数

import openpyxl as xl

work_book = xl.load_workbook('file_location')
sheet = work_book['Sheet1']
column_number = 2
column = str(chr(64 + column_number))
sheet.column_dimensions[column].width = 20
work_book.save('file_location')
Run Code Online (Sandbox Code Playgroud)


JAd*_*del 8

对于刚接触该主题的用户来说,这是一个更通用、简化的解决方案(未针对该问题指定)。

如果您想更改(版本 3.0.9)中单元格的宽度或高度,您只需通过或openpyxl指定单元格的属性即可完成。row_dimensionscolumn_dimensions

import openpyxl
wb = openpyxl.Workbook()
sheet = wb["Sheet"]


sheet["A1"] = "Tall row"
sheet["B2"] = "Wide column"

# Change height of row A1
sheet.row_dimensions[1].height = 100
# Change width of column B
sheet.column_dimensions["B"].width = 50

wb.save("StackOverflow.xlsx")
Run Code Online (Sandbox Code Playgroud)


Vir*_*ako 7

我有一个mergedcece和autosize的问题不能正常工作,如果你有同样的问题,你可以用下一个代码解决:

for col in worksheet.columns:
    max_length = 0
    column = col[0].column # Get the column name
    for cell in col:
        if cell.coordinate in worksheet.merged_cells: # not check merge_cells
            continue
        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)