2015-04-05 36 views
13

我想在Python的xlsxwriter中模擬Excel自動填充功能。根據這個URL,它不直接支持: http://xlsxwriter.readthedocs.io/worksheet.html在xslxwriter中模擬自動填充列

但是,它應該是相當簡單的循環,通過在紙張上的每個小區確定的最大大小列,只是使用worksheet.set_column(行,列,寬度)來設置寬度。

是不讓我只是寫這個的併發症是:

  1. 該URL並不指定哪些單位是第三個參數set_column。
  2. 我找不到一種方法來測量我想要插入單元格的項目的寬度。
  3. xlsxwriter似乎沒有讀回特定單元格的方法。這意味着我需要在寫入單元格時跟蹤每個單元格的寬度。如果我可以循環遍歷所有的單元格會更好,那樣就可以編寫一個通用的例程。
+1

試圖設置自動寬度也不是那麼簡單。字形寬度取決於字體。而如果你寫方程到單元格中呢?然後,根據寫入的內容,您無法確定單元格的寬度。單位是任意的,這是真的,但有一個實際的定義!一個單位接近默認字體中一個字符的寬度。請參閱https://support.microsoft.com/en-us/kb/214123 – 2015-07-24 15:12:03

+0

有關xlwt的相關問題(對於XlsxWriter,總體方法將與此相同;儘管您可能需要Calibri 11而不是Arial 10的寬度) :http://stackoverflow.com/questions/6929115/python-xlwt-accessing-existing-cell-content-auto-adjust-column-width/23946840 – 2016-05-13 15:37:00

回答

2

我最近遇到了同樣的問題,這就是我想出了:

r = 0 
c = 0 
for x in list: 
    worksheet.set_column('{0}:{0}'.format(chr(c + ord('A'))), len(str(x)) + 2) 
    worksheet.write(r, c, x) 
    c += 1 

在我的例子r將是你輸出的行號,c將是列數你正在輸出(均爲0索引),並且x將是您想要在單元中的list的值。

'{0}:{0}'.format(chr(c + ord('A')))片採用列數設置並將其轉換成由xlsxwriter接受列字母,因此,如果c = 0set_column會看到'A:A',如果c = 1那麼它會看到'B:B',依此類推。

len(str(x)) + 2作品確定您嘗試輸出的字符串的長度,然後向其中添加2以確保excel單元足夠寬,因爲字符串的長度與單元格的寬度不完全相關。你可能想玩,而不是你添加2或可能更多取決於你的數據。

xlsxwriter接受的單位有點難以解釋。當你在excel中時,你將鼠標懸停在可以改變列寬的地方,你會看到Width: 8.43 (64 pixels)。在這個例子中,它接受的單位是8.43,我認爲它是釐米?但是,excel甚至不提供一個單位,至少不是明確的。

注意:我只對包含1行數據的excel文件試過這個答案。如果你將有多行,你需要有一種方法來確定哪一行將有'最長'的信息,並只應用於該行。但是,如果每列的大小大致相同,無論哪一行,那麼這應該適合你。

祝你好運,我希望這有助於!

10

作爲一般規則,您希望列的寬度稍大於列中最長字符串的大小。 1個xlsxwriter列的單位大約等於一個字符的寬度。因此,您可以通過將每列設置爲該列中的最大字符數來模擬自動調整。

每個示例中,我傾向於在使用pandas數據框和xlsxwriter時使用下面的代碼。

它首先找到索引的最大寬度,該索引始終是熊貓精通渲染數據幀的左列。然後,它將返回所有值的最大值和每個從左到右移動的其餘列的列名稱。

對於您使用的任何數據來說,修改此代碼不應太難。

def get_col_widths(dataframe): 
    # First we find the maximum length of the index column 
    idx_max = max([len(str(s)) for s in dataframe.index.values] + [len(str(dataframe.index.name))]) 
    # Then, we concatenate this to the max of the lengths of column name and its values for each column, left to right 
    return [idx_max] + [max([len(str(s)) for s in dataframe[col].values] + [len(col)]) for col in dataframe.columns] 

for i, width in enumerate(get_col_widths(dataframe)): 
    worksheet.set_column(i, i, width) 
+0

什麼是指標? – 2017-06-06 20:59:44

+0

對不起,指標是數據框的名稱。爲了清楚起見,更新了答案以說明數據框 – 2017-06-19 17:45:08

4

我同意科爾鑽石。我需要做一些非常相似的事情,對我來說工作得很好。其中self.columns是我的專欄

def set_column_width(self): 
    length_list = [len(x) for x in self.columns] 
    for i, width in enumerate(length_list): 
     self.worksheet.set_column(i, i, width) 
1

的名單還有另一種解決方法,以模擬我發現Github site of xlsxwriter自動調整。我修改它返回水平文本(列寬)或90°旋轉的文本(行高度)的近似大小:

from PIL import ImageFont 

def get_cell_size(value, font_name, font_size, dimension="width"): 
    """ value: cell content 
     font_name: The name of the font in the target cell 
     font_size: The size of the font in the target cell """ 
    font = ImageFont.truetype(font_name, size=font_size) 
    (size, h) = font.getsize(str(value)) 
    if dimension == "height": 
     return size * 0.92 # fit value experimentally determined 
    return size * 0.13  # fit value experimentally determined 

這並不解決粗體文字或其他格式元素可能影響文本尺寸。否則,它工作得很好。

要查找列寬度自動調整:

def get_col_width(data, font_name, font_size, min_width=1): 
    """ Assume 'data' to be an iterable (rows) of iterables (columns/cells) 
    Also, every cell is assumed to have the same font and font size. 
    Returns a list with the autofit-width per column """ 
    colwidth = [min_width for col in data[0]] 
    for x, row in enumerate(data): 
     for y, value in enumerate(row): 
      colwidth[y] = max(colwidth[y], get_cell_size(value, font_name, font_size)) 
    return colwidth