2012-11-30 154 views
4

我有一個腳本需要一個pandas數據框並將其分成幾百個塊,並將每個塊保存爲一個單獨的excel文件。每個塊將具有相同的列數,但行數不同。我已經想出瞭如何使用openpyxl將所有其他必要的格式應用於這些文件,但我還沒有確定應用邊界的最快方式。此外,我認爲我只是沒有正確應用邊框,因爲下面的代碼(我懷疑不應該需要逐個遍歷每個單元格)不應用任何邊框。使用openpyxl將範圍應用到範圍內的所有單元格

from openpyxl.style import Border 

wb = load_workbook(filename = _fname) 
ws = wb.worksheets[0] 
for _row in ws.range('A1:L'+str(ws.get_highest_row())): 
    for _cell in _row: 
      _cell.style.borders.left.border_style = Border.BORDER_THIN 
      _cell.style.borders.right.border_style = Border.BORDER_THIN 
      _cell.style.borders.top.border_style = Border.BORDER_THIN 
      _cell.style.borders.bottom.border_style = Border.BORDER_THIN 
wb.save(_fname) 

所以這個代碼工作,但它並不適用於我預計(在Excel中默認邊框)的邊界,它需要更多的步驟比我更喜歡。我的期望是,我應該可以這樣做:

from openpyxl.style import Border 

wb = load_workbook(filename = _fname) 
ws = wb.worksheets[0] 

_range = ws.some_range_func('A1:L'+str(ws.get_highest_row())): 
    _range.style.borders.all_borders = Borders.BORDER_THIN 

此功能是否存在?如果不是,有人可以請至少解釋如何應用默認的邊框樣式,而不是這個稍厚的邊框? Border.BORDER_THICK,Border.BORDER_MEDIUM,Border.BORDER_THIN或Border.BORDER_HAIR都不正確。

謝謝!

回答

1

,如果你需要的熊貓造型(邊界...)擅長數據幀我的叉子剛剛合併到主 https://github.com/pydata/pandas/pull/2370#issuecomment-10898427

爲您邊界問題。 一次設置所有邊界不會縫在openpyxl中工作。

In [34]: c.style.borders.all_borders.border_style = openpyxl.style.Border.BORDER_THIN 

In [36]: c.style 
'Calibri':11:False:False:False:False:'none':False:'FF000000':'none':0:'FFFFFFFF':'FF000000':'none':'FF000000':'none':'FF000000':'none':'FF000000':'none':'FF000000':'none':'FF000000':0:'thin':'FF000000':'none':'FF000000':'none':'FF000000':'none':'FF000000':'none':'FF000000':'general':'bottom':0:False:False:0:'General':0:'inherit':'inherit' 

分別設定工作( '薄': 'FF000000')

In [37]: c.style.borders.top.border_style = openpyxl.style.Border.BORDER_THIN 

In [38]: c.style 
Out[38]: 'Calibri':11:False:False:False:False:'none':False:'FF000000':'none':0:'FFFFFFFF':'FF000000':'none':'FF000000':'none':'FF000000':'thin':'FF000000':'none':'FF000000':'none':'FF000000':0:'thin':'FF000000':'none':'FF000000':'none':'FF000000':'none':'FF000000':'none':'FF000000':'general':'bottom':0:False:False:0:'General':0:'inherit':'inherit' 

也許在openpyxl的錯誤。但沒什麼大不了的只是包裝設置頂部,底部,左,右的功能

+0

等等,所以在你的改變中,我應該能夠在我對df.to_excel()的調用中應用XLSX樣式?你可以給我演示一下這個過程是如何工作的,並且解釋我需要做什麼來更新我的熊貓版本以包含你的功能? –

+0

只需克隆主機並從源代碼安裝即可。 df.to_excel將爲標題,粗體名稱,合併多重索引添加邊框...這是一張圖片http://cl.ly/image/2r102L0E1l23。它會自動啓動。你可以看看源代碼來解決你的問題 – locojay

+0

我想應用我自己的風格,所以這不是我所需要的。聽起來最好的方式就是我已經在做的事情。謝謝! –

4

可能這很方便:

from openpyxl.reader.excel import load_workbook 
from openpyxl.style import Border 

def set_border(ws, cell_range): 
    rows = ws.range(cell_range) 
    for row in rows: 
     row[0].style.borders.left.border_style = Border.BORDER_THIN 
     row[-1].style.borders.right.border_style = Border.BORDER_THIN 
    for c in rows[0]: 
     c.style.borders.top.border_style = Border.BORDER_THIN 
    for c in rows[-1]: 
     c.style.borders.bottom.border_style = Border.BORDER_THIN 

#usage example: 
ws = load_workbook('example.xlsx').get_active_sheet() 
set_broder(ws, "C3:H10") 

它執行速度相當快。

2

@ user698585你的方法看起來不錯,但它不再工作了,因爲當前版本的openpyxl改變了實現。所以這應該被更新成例如

ws.cell(row=1, column=1).style.border.top.border_style = borders.BORDER_MEDIUM 

但它導致一個錯誤,即不允許更改樣式。 作爲一種解決方法,我只是定義了專用的樣式,但它們只是現有樣式和邊框定義的重複 - 不是很好的解決方案,只有在知道樣式具有更改後的單元時纔有效。

border_style = Style(font=Font(name='Console', size=10, bold=False, 
         color=Color(openpyxl.styles.colors.BLACK)), 
         fill=PatternFill(patternType='solid', fgColor=Color(rgb='00C5D9F1')), 
         border=Border(bottom=Side(border_style='medium', color=Color(rgb='FF000000')))) 
+0

樣式是不可變的,因爲它們可能被不同的單元共享。改變單元格樣式的最好方法是使用'.copy()'並傳入想要更改的部分。 –

1

決定,對openpyxl 2.3.5

from openpyxl.styles import Border, Side 

def set_border(ws, cell_range): 
    border = Border(left=Side(border_style='thin', color='000000'), 
       right=Side(border_style='thin', color='000000'), 
       top=Side(border_style='thin', color='000000'), 
       bottom=Side(border_style='thin', color='000000')) 

    rows = ws.range(cell_range) 
    for row in rows: 
     for cell in row: 
      cell.border = border 

set_border(worksheet, 'A5:C10') 
-1

工作似乎沒有內置的這項任務,我們必須作出一些自己的步驟,比如:

#need make conversion from alphabet to number due to range function 
def A2N(s,e): 
    return range(ord(s), ord(e)+1) 
#B1 is the border you defined 
#Assume you trying border A1-Q1 ... A3-Q3 
X = A2N('A','Q') 
#print X  
your_desired_sheet_range_rows = range(1,4) 
#need two loop to go through cells 
for row in your_desired_sheet_rows: 
    for col in X: 
     ca = chr(col) 
     sheet[ca+str(row)].border=B1 
相關問題