2013-05-08 3 views
4

단어가 포함되거나 특정 문자열로 끝나는 셀이 특정 색상으로 배경을 채워서 포맷되도록 스프레드 시트 (xls 또는 xlsx)를 포맷하고 싶습니다.조건부로 파이썬을 사용하여 Excel에서 텍스트 문자열 서식 지정

예를 들어, 셀에 'deleted'라는 단어가 포함되어 있으면 검정색으로 채우고 흰색으로 칠하십시오. 셀이 '.pf'로 끝나면 셀을 빨간색으로 페인트합니다. 이 output.xls에 input.xls에서 값을 복사 않지만

import xlrd 
import xlutils.copy 

inBook = xlrd.open_workbook('input.xls', formatting_info=True) 
outBook = xlutils.copy.copy(inBook) 

def _getOutCell(outSheet, colIndex, rowIndex): 
    """ HACK: Extract the internal xlwt cell representation. """ 
    row = outSheet._Worksheet__rows.get(rowIndex) 
    if not row: return None 
    cell = row._Row__cells.get(colIndex) 
    return cell 

def setOutCell(outSheet, col, row, value): 
    """ Change cell value without changing formatting. """ 
    # HACK to retain cell style. 
    previousCell = _getOutCell(outSheet, col, row) 
    # END HACK, PART I 
    outSheet.write(row, col, value) 
    # HACK, PART II 

    if previousCell: 
     newCell = _getOutCell(outSheet, col, row) 
    if newCell: 
     newCell.xf_idx = previousCell.xf_idx 
    # END HACK 


outSheet = outBook.get_sheet(0) 
setOutCell(outSheet, 5, 5, 'Test') 
outBook.save('output.xls') 

, 이것은 서식을 전송하지 않는 것합니다 (:

나는 다음과 같은 제안 몇 년 전 비슷한 질문을 발견 input.xls의 테스트 값은 output.xls를 열 때 더 이상 형식화되지 않으며 Excel의 "규칙 관리"아래에 조건부 서식 규칙이 없으며 숫자 값에 대한 명령문이 작동하는 것처럼 보일 수도 있지만 다시 I 특정 문자열이 들어있는 셀을 포맷하는 방법을 찾고 있습니다. 감사합니다.

+0

파일을 현재 위치에서 변경하려고 시도 했습니까? 스크립트를 실행하기 전에 파일의 백업을 만들 수 있습니다. – Alfe

+0

제 생각에는 편집을 할 수 있다고 생각하지 않습니다. 나는 xlutils가 단지 당신이 사본을 복사하고 수정할 수 있다고 이해한다. win32com이이 작업을 수행 할 수 있다면 시도해 볼 수있는 멋진 방향이 될 수 있지만 그 사실을 인식하지 못합니다. win32com은 또한이 스크립트가 excel (Linux)이 설치되지 않은 컴퓨터에서 작동하기를 원하기 때문에 필자가 선호하는 전술이 아닙니다. – user2363458

답변

2

당신이 그것을 열 때 원래 input.xls 서식을 보존 :

from xlrd import open_workbook 

input_wb = open_workbook('input.xls', formatting_info=True) 

이 템플릿을 기반으로 새 통합 문서 만들기 :

from xlutils.copy import copy as copy_workbook 

output_wb = copy_workbook(input_wb) 

몇 가지 새로운 셀 스타일 정의 :

from xlwt import easyxf 

red_background = easyxf("pattern: pattern solid, fore_color red;") 
black_with_white_font = easyxf('pattern: pattern solid, fore_color black; font: color-index white, bold on;") 

는 평가를 세포를 수정하십시오 :

input_ws = input_wb.sheet_by_name('StackOverflow') 
output_ws = output_wb.get_sheet(0) 

for rindex in range(0, input_ws.nrows): 
    for cindex in range(0, input_ws.ncols): 
     input_cell = input_ws.cell(rindex, cindex) 
     if input_cell.value[ input_cell.value.rfind('.'): ] == 'pf': 
      output_ws.write(rindex, cindex, input_cell.value, red_background) 
     elif input_cell.value.find('deleted') >= 0: 
      output_ws.write(rindex, cindex, input_cell.value, black_with_white_font) 
     else: 
      pass # we don't need to modify it 

위의 예제를 사용하여 새 통합 문서

output_wb.save('output.xls') 

저장, 수정되지 않은 세포는 자신의 원래 서식은 그대로 있어야합니다.

을 사용하면 셀 내용을 변경해야해야하며 원래 서식을 보존하고자하는 (사용자 정의 easyxf 인스턴스를 사용하지 IE),이 조각 사용할 수 있습니다 다음 비교를 들어

def changeCell(worksheet, row, col, text): 
    """ Changes a worksheet cell text while preserving formatting """ 
    # Adapted from https://stackoverflow.com/a/7686555/1545769 
    previousCell = worksheet._Worksheet__rows.get(row)._Row__cells.get(col) 
    worksheet.write(row, col, text) 
    newCell = worksheet._Worksheet__rows.get(row)._Row__cells.get(col) 
    newCell.xf_idx = previousCell.xf_idx 

# ... 

changeCell(worksheet_instance, 155, 2, "New Value") 

을, 문자열 메서드 findrfind (오른쪽에서 검색)을 사용할 수 있습니다. 문자열 내 하위 문자열 위치의 인덱스를 반환합니다. 하위 문자열이 없으면 -1을 반환합니다. Ergo, input_cell.value.find('deleted') >= 0 이상에서 'deleted'하위 문자열이 있는지 여부를 판단 할 수 있습니다. .pf 비교를 위해 slicing이라는 파이썬의 내용과 rfind을 사용했습니다.

+0

이 다음과 같은 오류가 발생합니다'역 추적 (마지막으로 가장 최근 통화) : ". \ stacksolution.py" 파일 = input.sheet_by_name ('시트 1') #eval input_ws과에서, 라인 (14), 세포에게 AttributeError를 수정 : 'builtin_function_or_method 객체에는'sheet_by_name '속성이 없습니다 ... 또한, 문자열 비교를 로직에 적용하는 방법이 명확하지 않습니다. 예를 들어 'if input_cell.value =='논리가 여기에 있습니다 .. '<50 or > 60'이라고 말하면 괜찮습니다. 그러나 ".pf로 끝납니다"또는 "word delete가 들어 있습니다. 어딘가에 문자열이 있습니다. " – user2363458

+1

오류의 경우 실제로는 'input_wb'('output_wb'와 동일) 일 때 통합 문서 인스턴스 이름으로 '입력'을 입력 했으므로이 두 행을 반드시 업데이트해야합니다. 조건부 표현을 몇 가지로 보여주기 위해 – pztrick

+0

이것은 지금까지 최고의 결과입니다 input_wb 및 output_wb에 대한 오타 수정을 사용하여 스크립트는 이제 모든 셀 내용으로 input.xls를 output.xls에 성공적으로 복사합니다. 폰트 타입, 폰트 사이즈, 폰트 컬러와 같은 포맷팅 ** 이것이 아닌 ** 조건부 포맷팅이나 조건부 포맷팅 룰을 유지하고있다. (아마 xlutils.copy의 제한 사항이다.) 당신이 제공 한 로직은 어딘가에 '삭제'라는 단어가 들어있는 파일 그 (것)들 n 그러나, 아닙니다 .pf '. 'delete'문을 '.pf'와 함께 사용하면 몇 가지 오 탐지 (false positive)가 발생합니다. 감사! – user2363458