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

时间:2011-08-03 15:33:39

标签: python xlwt xlrd

我正在尝试创建一个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 DOES提供我正在寻找的功能,我计划再次浏览每个工作表,但这次要跟踪占用特定列的空间最多的内容,并根据该列设置列宽。 。当然,我也可以在写入工作表时跟踪特定列的最大宽度,但我觉得在已经写完所有数据后设置宽度会更清晰。

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

6 个答案:

答案 0 :(得分: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)

所有魔法都在John Yeung's arial10 module。这具有Arial 10的宽度,这是默认的Excel字体。如果要使用其他字体编写工作表,则需要更改fitwidth函数,最好考虑传递给style的{​​{1}}参数。

答案 1 :(得分:5)

如果一个人对使用另一个类(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)

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

这是改编自Kevins FitSheetWrapper。

答案 2 :(得分:4)

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

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

答案 3 :(得分:1)

FitSheetWrapper应该在3.3.4

中对xlwt3进行一点修改

第19行:

改变:

width = arial10.fitwidth(label)

为:

width = int(arial10.fitwidth(label))  

原因:   \的Python \ 3.3.3 \ LIB \站点包\ xlwt3 \ biffrecords.py

1624 def __init__(self, first_col, last_col, width, xf_index, options):
1625        self._rec_data = pack('<6H', first_col, last_col, width, xf_index, options, 0)

宽度必须是整数。

答案 4 :(得分:1)

这可能有点晚了,但我创建了一个方法来完成整个过程 一下子。它很快就完成了工作。额外的垫子。只有在您认为256计算不准确时才需要(如果您有更长的文本字段)。

SELECT OrderId,[Item1],[Item2],[Item3],[Item4],[Item5],[Item6]
FROM
(
  SELECT 
  OrderID,N'Item'+ CAST (ROW_NUMBER() OVER(PARTITION BY OrderID Order by Item) AS NVARCHAR(25)) AS ItemNumber, Item FROM OrderItem
  )S
  PIVOT
  (
  MAX(Item) 
    FOR ItemNumber IN ([Item1],[Item2],[Item3],[Item4],[Item5],[Item6])
  )piv

答案 5 :(得分:0)

我使用这种方法:

wb = Workbook()
ws = wb.add_sheet('Sheet1')
columnwidth = {}
row = 0
for rowdata in data:
    column = 0
    for colomndata in rowdata:
        if column in columnwidth:
            if len(colomndata) > columnwidth[column]:
                columnwidth[column] = len(colomndata)
        else:
            columnwidth[column] = len(colomndata)
        ws.write(row, column, colomndata, style0)
        column = column + 1
    row = row + 1
for column, widthvalue in columnwidth.items():
    ws.col(column).width = (widthvalue + 4) * 367