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_MEDIUM, BORDER.테두리_Thin(얇음) 또는 Border(테두리).테두리_머리가 맞는 것 같아요.
감사합니다!
openpyxl==3.0.5에 대한 좀 더 파이썬적인 방법:
from openpyxl.styles import Border, Side
def set_border(ws, cell_range):
thin = Side(border_style="thin", color="000000")
for row in ws[cell_range]:
for cell in row:
cell.border = Border(top=thin, left=thin, right=thin, bottom=thin)
set_border(worksheet, 'A5:C10')
이것이 유용할 수도 있습니다.
from openpyxl.reader.excel import load_workbook
from openpyxl.style import Border
def set_border(ws, cell_range):
rows = was[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")
상당히 빠른 성능을 발휘합니다.
@Karimov에서 답변할 약간 수정 사항이 있습니다.
아래는 당신의 코드가 어떻게 되어야 하는지입니다.
from openpyxl.styles import Border, Side, Font, Alignment
def __format_ws__(self, 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[cell_range]
for row in rows:
for cell in row:
cell.border = border
목록 이해를 사용하는 훨씬 빠른 방법은 다음과 같습니다.
def __format_ws__(self, ws, cell_range):
#applying border and alignment
font = Font(size=9)
align=Alignment(horizontal='left', vertical='center')
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 = [rows for rows in ws[cell_range]]
flattened = [item for sublist in rows for item in sublist]
[(setattr(cell,'border',border), setattr(cell,'font',font), setattr(cell,'alignment',align)) for cell in flattened]
사용 방법은 다음과 같습니다.
self.__format_ws__(ws=writer.book.worksheets[0], cell_range='A1:G10')
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.iter_rows(cell_range)
for row in rows:
for cell in row:
cell.border = border
set_border(worksheet, 'A5:C10')
@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'))))
만약 당신이 판다들을 위한 스타일링(스타일링...)이 필요하다면, 내 포크는 방금 마스터 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'
개별적으로 설정하면 작동합니다('thin':).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의 버그일 것입니다. 하지만 큰 문제는 없습니다. 그냥 아래, 위, 왼쪽, 오른쪽 기능으로 랩 세팅만 하세요.
같은 문제가 있었지만 감가상각으로 인해 2019년에 이 문제를 해결할 수 있는 것을 찾을 수 없었습니다.아래에 작동하는 것이 있습니다.더 나을 수도 있지만 모든 목적과 목적에 효과가 있습니다.
def set_border(ws, cell_range):
rows = ws[cell_range]
for row in rows:
if row == rows[0][0] or row == rows[0][-1] or row == rows[-1][0] or row == rows[-1][-1]:
pass
else:
row[0].border = Border(left=Side(style='thin'))
row[-1].border = Border(right=Side(style='thin'))
for c in rows[0]:
c.border = Border(top=Side(style='thin'))
for c in rows[-1]:
c.border = Border(bottom=Side(style='thin'))
rows[0][0].border = Border(left=Side(style='thin'), top=Side(style='thin'))
rows[0][-1].border = Border(right=Side(style='thin'), top=Side(style='thin'))
rows[-1][0].border = Border(left=Side(style='thin'), bottom=Side(style='thin'))
rows[-1][-1].border = Border(right=Side(style='thin'), bottom=Side(style='thin'))
def set_border(ws, cell_range, style='thin'):
rows = ws[cell_range]
for row in rows:
temp_row = copy(row[0].border)
row[0].border = Border(left=Side(style=style), right=temp_row.right, top=temp_row.top, bottom=temp_row.bottom)
temp_row = copy(row[-1].border)
row[-1].border = Border(right=Side(style=style), left=temp_row.left, top=temp_row.top, bottom=temp_row.bottom)
for c in rows[0]:
temp_row = copy(c.border)
c.border = Border(top=Side(style=style), left=temp_row.left, bottom=temp_row.bottom, right=temp_row.right)
for c in rows[-1]:
temp_row = copy(c.border)
c.border = Border(bottom=Side(style=style), left=temp_row.left, top=temp_row.top, right=temp_row.right)
이렇게 하면 측면의 기존 테두리가 유지되며 테두리 스타일을 지정할 수도 있습니다.
이 작업에는 기본 제공되지 않으며, 다음과 같은 몇 가지 단계를 직접 수행해야 합니다.
#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
언급URL : https://stackoverflow.com/questions/13650059/apply-borders-to-all-cells-in-a-range-with-openpyxl
'programing' 카테고리의 다른 글
Powershell 스크립트에서 TeamCity 시스템 속성에 액세스할 수 있는 방법이 있습니까? (0) | 2023.09.07 |
---|---|
Spring 보안으로 로그인한 사용자에게 조건부로 jsp 컨텐츠를 보여주는 방법 (0) | 2023.09.07 |
gdb: gdb를 종료하지 않고 프로그램을 종료합니다. (0) | 2023.09.02 |
인덱스가 Laravel 마이그레이션에 있는지 확인하려면 어떻게 해야 합니까? (0) | 2023.09.02 |
Android Studio에서 데이터베이스 파일의 내용 보기 (0) | 2023.09.02 |