example - Preservar estilos usando python''s xlrd, xlwt, y xlutils.copy
xlrd python windows installer (2)
Aquí hay un ejemplo de uso de código que propongo como un parche contra 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()
Estoy usando xlrd
, xlutils.copy
y xlwt
para abrir un archivo de plantilla, copiarlo, llenarlo con nuevos valores y guardarlo.
Sin embargo, no parece haber una manera fácil de preservar el formato de las celdas; siempre sale volando y se pone en blanco. ¿Hay alguna manera simple de que pueda hacer esto?
¡Gracias! / YGA
Un script de ejemplo:
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'')
Versiones:
-
xlrd
: 0.7.1 -
xlwt
: 0.7.2
Hay dos partes para esto.
Primero, debe habilitar la lectura de información de formato al abrir el libro de trabajo de origen. La operación de copiado luego copiará el formateo.
import xlrd
import xlutils.copy
inBook = xlrd.open_workbook(''input.xls'', formatting_info=True)
outBook = xlutils.copy.copy(inBook)
En segundo lugar, debe lidiar con el hecho de que cambiar el valor de una celda restablece el formato de esa celda.
Esto es menos bonito; Uso el siguiente hack donde copio manualmente el índice de formato ( xf_idx
) sobre:
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'')
Esto conserva casi todo el formato. Sin embargo, los comentarios de la celda no se copian.