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

noo*_*lar 27 python xlrd xlwt

我正在尝试创建一个Excel工作簿,我可以在保存工作簿之前自动设置或自动调整列的宽度.

我一直在阅读的Python的Excel的教程中找到在xlwt是模仿xlrd者某些功能的希望(如sheet_names(),cellname(row, col),cell_type,cell_value,等...).例如,假设我有以下几点:

from xlwt import Workbook    
wb = Workbook()
sh1 = wb.add_sheet('sheet1' , cell_overwrite_ok = True)    
sh2 = wb.get_sheet(0)
Run Code Online (Sandbox Code Playgroud)

wb.get_sheet(0)类似于rb.sheet_by_index(0)xlrd中提供的功能,除了前者允许您修改内容(前提是用户已设置cell_overwrite_ok = True)

假设xlwt DOES提供了我正在寻找的功能,我计划再次浏览每个工作表,但这次要跟踪占用特定列的空间最多的内容,并根据该列设置列宽.当然,我也可以在写入工作表时跟踪特定列的最大宽度,但我觉得在已经写完所有数据后设置宽度会更清晰.

有谁知道我能做到吗?如果没有,你建议做什么来调整列宽?

Kev*_*n S 46

我刚刚实现了一个包装类,用于在输入项目时跟踪项目的宽度.它似乎工作得很好.

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)
Run Code Online (Sandbox Code Playgroud)

所有的魔力都在John Yeung的arial10模块中.这具有Arial 10的宽度,这是默认的Excel字体.如果要使用其他字体编写工作表,则需要更改fitwidth函数,最好考虑style传递给的参数FitSheetWrapper.write.

  • 链接到arial10模块对我来说是破碎的.但我在github上找到了它:https://github.com/GeekPeduli/Sahana-Eden/blob/master/modules/arial10.py (7认同)
  • 很好的解决方案.我不得不用`int(..)`包装`width = arial10.fitwidth(label)`,因为xlwt-0.7.5会引发一个ValueError.如果你得到一个小于所需的单元格宽度,请尝试`math.ceil(int(..))`. (5认同)
  • Humphrey的链接现在也被破坏了,但arial10似乎保留在这里:https://github.com/juanpex/django-model-report/blob/master/model_report/arial10.py (2认同)

小智 10

如果一个人对使用另一个类(FitSheetWrapper)不感兴趣,那么可以使用WorkSheet列Method来实现.

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)
Run Code Online (Sandbox Code Playgroud)

宽度的默认值为2962单位,excel指向8.11单位.因此,我将367乘以数据长度.

这是改编自Kevins FitSheetWrapper.


Joh*_*n Y 5

xlwt 中没有为此提供自动功能。您必须遵循您所描述的一般模式,在您编写时跟踪最大宽度,并在看到所有数据之后但在保存工作簿之前的某个时间设置列宽。

请注意,这处理 Excel 文件时可用的最干净、最有效的方法。如果您的“在数据已经写入之后”的概念意味着在您已经提交单元格值(“写入”)之后但在实际保存工作簿之前,那么上述方法就是这样做的。如果你的意思是在你已经保存了工作簿之后,你想再次阅读它以获得最大宽度,然后用新的列宽再次保存它,这会慢得多,并且将涉及同时使用 xlwt 和 xlrd(可能还有 xlutils)。另请注意,当您使用正版 Microsoft Excel 时,没有“更新”文件的概念。从用户的角度来看似乎是这样,但幕后发生的事情是,每次进行保存时,Excel 都会清除现有文件并从头开始编写一个全新的文件。