Preserving styles using python's xlrd,xlwt, and xlutils.copy

匿名 (未验证) 提交于 2019-12-03 01:48:02

问题:

I'm using xlrd, xlutils.copy, and xlwt to open up a template file, copy it, fill it with new values, and save it.

However, there doesn't seem to be any easy way to preserve the formatting of the cells; it always gets blown away and set to blank. Is there any simple way I can do this?

Thanks! /YGA

A sample script:

from xlrd import open_workbook from xlutils.copy import copy rb = open_workbook('output_template.xls',formatting_info=True) rs = rb.sheet_by_index(0) wb = copy(rb) ws = wb.get_sheet(0) for i,cell in enumerate(rs.col(8)):     if not i:         continue     ws.write(i,2,22,plain) wb.save('output.xls') 

Versions:

  • xlrd: 0.7.1
  • xlwt: 0.7.2

回答1:

There are two parts to this.

First, you must enable the reading of formatting info when opening the source workbook. The copy operation will then copy the formatting over.

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

Secondly, you must deal with the fact that changing a cell value resets the formatting of that cell.

This is less pretty; I use the following hack where I manually copy the formatting index (xf_idx) over:

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') 

This preserves almost all formatting. Cell comments are not copied, though.



回答2:

Here's an example of usage of code that I'll propose as a patch against xlutils 1.4.1

# coding: ascii  import xlrd, xlwt  # Demonstration of copy2 patch for xlutils 1.4.1  # Context: # xlutils.copy.copy(xlrd_workbook) -> xlwt_workbook # copy2(xlrd_workbook) -> (xlwt_workbook, style_list) # style_list is a conversion of xlrd_workbook.xf_list to xlwt-compatible styles  # Step 1: Create an input file for the demo def create_input_file():     wtbook = xlwt.Workbook()     wtsheet = wtbook.add_sheet(u'First')     colours = 'white black red green blue pink turquoise yellow'.split()     fancy_styles = [xlwt.easyxf(         'font: name Times New Roman, italic on;'         'pattern: pattern solid, fore_colour %s;'          % colour) for colour in colours]     for rowx in xrange(8):         wtsheet.write(rowx, 0, rowx)         wtsheet.write(rowx, 1, colours[rowx], fancy_styles[rowx])     wtbook.save('demo_copy2_in.xls')  # Step 2: Copy the file, changing data content # ('pink' -> 'MAGENTA', 'turquoise' -> 'CYAN') # without changing the formatting  from xlutils.filter import process,XLRDReader,XLWTWriter  # Patch: add this function to the end of xlutils/copy.py def copy2(wb):     w = XLWTWriter()     process(         XLRDReader(wb,'unknown.xls'),         w         )     return w.output[0][1], w.style_list  def update_content():     rdbook = xlrd.open_workbook('demo_copy2_in.xls', formatting_info=True)     sheetx = 0     rdsheet = rdbook.sheet_by_index(sheetx)     wtbook, style_list = copy2(rdbook)     wtsheet = wtbook.get_sheet(sheetx)     fixups = [(5, 1, 'MAGENTA'), (6, 1, 'CYAN')]     for rowx, colx, value in fixups:         xf_index = rdsheet.cell_xf_index(rowx, colx)         wtsheet.write(rowx, colx, value, style_list[xf_index])     wtbook.save('demo_copy2_out.xls')  create_input_file() update_content() 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!