2010-09-16 6 views
47

J'utilise xlrd, xlutils.copy et xlwt pour ouvrir un fichier de modèle, le copier, le remplir de nouvelles valeurs et l'enregistrer.Préserver les styles à l'aide de xlrd, xlwt et xlutils.copy de python

Cependant, il ne semble pas y avoir de moyen facile de préserver le formatage des cellules; il est toujours époustouflé et mis à blanc. Y a-t-il un moyen simple de le faire?

Merci! /YGA

Un exemple de 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

Répondre

10

Voici un exemple d'utilisation de code que je vais proposer en patch contre 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() 
+0

Une meilleure solution serait d'ajouter xlwt 'wb.write_value (row, col, value)'. Cela fonctionne, mais a beaucoup de puanteur de code dans mon livre, en travaillant autour d'une mauvaise implémentation de xlwt. – boatcoder

+0

Est-ce que cela est déjà arrivé? – YGA

42

Il y a deux parties à cela. D'abord, vous devez activer la lecture des informations de formatage lors de l'ouverture du classeur source. L'opération de copie va ensuite copier le formatage. Deuxièmement, vous devez faire face au fait que la modification d'une valeur de cellule réinitialise la mise en forme de cette cellule.

C'est moins joli; J'utilise le hack où je copier manuellement l'index de formatage (xf_idx) sur:

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

Cela préserve presque tout le formatage. Les commentaires de cellule ne sont pas copiés, cependant.

+0

mais le référencement des cellules dans les autres feuilles est manquant! – deeshank

Questions connexes