2010-09-16 33 views
47

Sto utilizzando xlrd, xlutils.copy e xlwt per aprire un file modello, copiarlo, riempirlo con nuovi valori e salvarlo.Conservazione degli stili utilizzando python's xlrd, xlwt e xlutils.copy

Tuttavia, non sembra essere un modo semplice per preservare la formattazione delle celle; viene sempre spazzato via e lasciato vuoto. C'è un modo semplice per farlo?

Grazie! /YGA

uno script di esempio:

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

Versioni:

  • xlrd: 0.7.1
  • xlwt: 0.7.2

risposta

10

Ecco un esempio di utilizzo di codice che proporrò come patch contro 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

Una soluzione migliore sarebbe xlwt aggiungendo un 'wb.write_value (row, col, value)'. Funziona, ma ha un sacco di codice puzzare nel mio libro, aggirando una scarsa implementazione di xlwt. – boatcoder

+0

È mai successo? – YGA

42

Ci sono due parti in questo.

Innanzitutto, è necessario abilitare la lettura delle informazioni di formattazione quando si apre la cartella di lavoro di origine. L'operazione di copia quindi copierà la formattazione.

import xlrd 
import xlutils.copy 

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

In secondo luogo, è necessario considerare il fatto che la modifica di un valore di cella reimposta la formattazione di tale cella.

Questo è meno bello; Io uso il seguente trucco dove copio manualmente l'indice di formattazione (xf_idx) su:

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

Questa conserva quasi tutta la formattazione. Tuttavia, i commenti delle celle non vengono copiati.

+0

ma manca il riferimento alle celle negli altri fogli! – deeshank

Problemi correlati