Python xlwt - 访问现有单元格内容,自动调整列宽

34 投票
6 回答
41251 浏览
提问于 2025-04-16 22:48

我正在尝试创建一个Excel工作簿,希望在保存之前能够自动设置或调整列的宽度。

我在阅读Python-Excel的教程,想找到一些xlwt中的函数,能模仿xlrd中的函数,比如sheet_names()cellname(row, col)cell_typecell_value等等。举个例子,假设我有以下内容:

from xlwt import Workbook    
wb = Workbook()
sh1 = wb.add_sheet('sheet1' , cell_overwrite_ok = True)    
sh2 = wb.get_sheet(0)

wb.get_sheet(0)这个函数类似于xlrd中的rb.sheet_by_index(0),不过前者允许你修改内容(前提是用户设置了cell_overwrite_ok = True)。

假设xlwt确实提供了我需要的函数,我打算再遍历每个工作表,这次记录下每一列中占用空间最多的内容,然后根据这个来设置列宽。当然,我也可以在写入数据时记录每一列的最大宽度,但我觉得在所有数据写完后再设置宽度会更整洁。

有没有人知道我能否这样做?如果不行,你们有什么建议来调整列宽吗?

6 个回答

5

在xlwt这个库里,没有自动处理这个问题的功能。你需要按照你描述的方式来做,也就是在写数据的时候,自己记录下每一列的最大宽度,然后在最后设置列宽,这个过程是在你看到所有数据之后,但在保存工作簿之前进行的。

需要注意的是,这种方法是处理Excel文件时最干净、最有效的方式。如果你所说的“在数据已经写入之后”是指在你已经输入了单元格的值(即“写入”)但还没有真正保存工作簿之前,那么上面描述的方法正是这样做的。如果你指的是在你已经保存了工作簿之后,再去读取它以获取最大宽度,然后再用新的列宽保存一次,那么这个过程会慢很多,并且需要同时使用xlwt和xlrd(可能还需要xlutils)。另外,使用真正的Microsoft Excel时,并没有“更新”文件的概念。从用户的角度看可能是这样,但实际上每次你保存时,Excel都会删除现有的文件,然后从头开始写一个全新的文件。

15

如果你不想使用另一个类(FitSheetWrapper),那么可以通过工作表的列方法来实现这个功能。

work = xlwt.WorkBook()
sheet = work.add_sheet('Sheet1')
for row_index in range(0,max_row):
   for column_index in range(0,max_col) :
      cwidth = sheet.col(column_index).width
      if (len(column_data)*367) > cwidth:  
          sheet.col(column_index).width = (len(column_data)*367) #(Modify column width to match biggest data in that column)

      sheet.write(row_index,column_index,column_data,style)

默认的宽度值是2962个单位,在Excel中显示为8.11个单位。所以我把数据的长度乘以367。

这个方法是从Kevin的FitSheetWrapper中改编过来的。

50

我刚刚实现了一个包装类,它可以在你输入项目时跟踪这些项目的宽度。看起来效果还不错。

import arial10

class FitSheetWrapper(object):
    """Try to fit columns to max size of any entry.
    To use, wrap this around a worksheet returned from the 
    workbook's add_sheet method, like follows:

        sheet = FitSheetWrapper(book.add_sheet(sheet_name))

    The worksheet interface remains the same: this is a drop-in wrapper
    for auto-sizing columns.
    """
    def __init__(self, sheet):
        self.sheet = sheet
        self.widths = dict()

    def write(self, r, c, label='', *args, **kwargs):
        self.sheet.write(r, c, label, *args, **kwargs)
        width = arial10.fitwidth(label)
        if width > self.widths.get(c, 0):
            self.widths[c] = width
            self.sheet.col(c).width = width

    def __getattr__(self, attr):
        return getattr(self.sheet, attr)

所有的关键都在John Yeung的arial10模块里。这个模块提供了Arial 10字体的合适宽度,而Arial 10是Excel的默认字体。如果你想用其他字体来写工作表,就需要修改fitwidth函数,最好是考虑传给FitSheetWrapper.writestyle参数。

撰写回答