Kspread y Python Nos Ofrecen Una Forma Simple de Realizar Facturas Automáticas.
Kspread y Python Nos Ofrecen Una Forma Simple de Realizar Facturas Automáticas.
Kspread y Python Nos Ofrecen Una Forma Simple de Realizar Facturas Automáticas.
Kspread y Python nos ofrecen una forma simple de realizar facturas automticas.
FACTURACIN
Python no slo puede ayudarnos en nuestro ordenador personal, sino tambin en el del trabajo. Vamos a ver cmo sacar el mximo partido a KOffice 1.6 con Python y Kross, el nuevo sistema de scripting que KDE incorporar en la versin 4.0. POR JOSE MARA RUZ AGUILERA
a gente de KDE se encontraba ante un dilema. Necesitaban incorporar algn sistema de scripts en la nueva versin de Koffice. No pensaban reinventar la rueda, existiendo tantos intrpretes y lenguajes con comunidades fuertes y miles de
Listado 1: holamundo.py
01 #!/usr/bin/env krossrunner 02 03 import krosskspreadcore 04 05 doc = krosskspreadcore.get(KSpreadD ocument) 06 07 hoja = doc.currentSheet() 08 09 hoja.setName(Hola Mundo) 10 11 celda = hoja.cell(1,1) 12 celda.setText(Hola Mundo)
libreras, y por ello decidieron crear Kross. Kross permite emplear lenguajes script como Python o Ruby dentro de KDE. De hecho, ser parte integrante de KDE 4 y no slo de Koffice 1.6, como hasta el momento. Por lo tanto, en un futuro muy prximo ser posible crear scripts que saquen el mximo partido de todo KDE 4. Pero eso ser dentro de algn tiempo. Ahora vamos a concentrarnos en lo que podemos hacer ahora. Mejor an, en lo que podemos hacer ahora y que nos pueda hacer la vida ms sencilla. Como demostracin del scripting de Python a travs de Kross vamos a crear un programa que genere facturas a partir de una base de datos, Python y una plantilla de factura.
mos instalar con nuestro sistema de paquetes favorito el programa Koffice cuya versin sea superior a 1.6. Todas las versiones de Koffice superiores a 1.6 dependen de Kross, por lo que nuestro sistema de paquetes probablemente instalar Kross, as como todas las dependencias asociadas. Kross es muy reciente. De hecho el API para la versin 1.6.2 es realmente pequeo. Algunos diran que incluso poco til, pero an as se le puede sacar partido. Se encuentra an en fase de prototipo, la versin 2.0 de Koffice ofrecer un soporte muchsimo ms amplio con todas las funcionalidades que Koffice puede ofrecer, de forma que podremos hacer casi cualquier cosa con Kross. Por el momento Kross no es una librera que podamos importar, por lo que debemos ejecutar nuestros scripts dentro de Koffice empleando el mecanismo que veremos ms adelante. El cdigo que aparece como ejemplo en la prxima seccin no puede ejecutarse en un intrprete normal de Python. La prxima versin de Kross permitir su carga como librera en cualquier intrprete de Python, lo que har mucho ms sencilla la ejecucin de scripts.
Kross
Qu necesitamos para poder emplear Kross? Pues realmente, slo necesita-
API Actual
Como ya se ha dicho, la API de Kspread (ver [1]) actual es muy simple. Tanto que slo consta de 4 objetos y sus mtodos:
WWW.LINUX- MAGAZINE.ES
Nmero 28
53
KSpreadCoreModule (representa a Kspread) Doc (representa a un documento) Sheet (representa una hoja) Cell (representa una celda) El primero, de nombre ms complicado, realmente slo lo emplearemos una vez y con su mtodo get(). Sirve para invocar la creacin de una instancia de Kspread:
>>> doc = krosskspreadcore.getU (KSpreadDocument) >>>
La variable doc contiene ahora un objeto que nos permite acceder al documento dentro de KSpread, que no ser otra cosa que una hoja de clculo. sta se compone de diferentes pginas (o sheets) con un nombre. Estas pginas contienen a su vez celdas y las celdas contienen valores. Kspread nos ofrece exactamente la misma jerarqua. Para poder llegar a modificar el valor de una celda necesitamos primero acceder a un documento, despus a una pgina y por ltimo a la celda en cuestin. Cada pgina est compuesta por una cantidad de filas y columnas, y una celda est identificada por su fila y su columna. El objeto Doc posee mtodos para operar con las pginas que contiene. Con currentSheet() podemos obtener la hoja que se encuentra seleccionada en ese momento (que no es otra que la que vemos), si queremos acceder a otra hoja debemos emplear su nombre. Podemos obtener los nombres de las diferentes hojas con el mtodo sheetNames() que
En nuestros ejemplos emplearemos el mtodo currentSheet() porque nos vale con la primera hoja. Una vez que tenemos nuestra hoja almacenada en una variable, es posible acceder a una celda en particular con el mtodo cell() del objeto Sheet. Pero, repito, tener la celda no es tener el valor que sta guarda. Para ello debemos almacenar en una variable el resultado de la llamada a cell():
>>> hoja = doc.currentSheet() >>> celda = hoja.cell(1,1)
mtodo setText(), que nos permite almacenar una cadena de texto. Pero esta cadena es posteriormente interpretada por Kspread. Por tanto, podemos pasar como cadena de texto una fecha o un nmero. El mtodo setValue() no introduce una cadena de texto a no ser que le pasemos una. Intenta insertar el dato tal como es, no se interpreta nada. Bueno, ya est bien de teora. Veamos cmo podemos crear nuestros propios scripts y usarlos desde Kspread.
Hola Mundo
En el Listado 1 aparece el cdigo que escribir Hola mundo tanto en el nombre de la hoja como en la celda (1,1) de una hoja de clculo. Pero qu hacemos con l? Debemos indicarle a Kspread que lo cargue para que podamos ejecutarlo. Para ello debemos ir al gestor de Scripts en el men Herramientas. Cuando lo ejecutemos aparecer una ventana muy parecida a la que se ve en la Figura 1. En ella podemos distinguir 3 secciones: Scripts, Cargados e Historial (en mi caso aparece en ingls). La seccin Scripts se refiere a una serie de scripts que se encuentran almacenados en un directorio especial. Adems, vienen acompaados de un fichero rc que da a Kspread datos sobre el script. Estos scripts son cargados cada vez que Kspread se arranca. Pero a veces no queremos andar arrancando y apagando Kspread para probar nuestros scripts, simplemente queremos cargarlos, probarlos y descargarlos para volver otra vez a cargarlos. Este ciclo de trabajo es normal cuando se est trabajando en un script nuevo. Pues con el gestor de scripts podemos
Las celdas estn numeradas comenzando por 1, pero por alguna decisin realizada por los desarrolladores de Kspread es posible acceder a la celda 0, que no es otra que la 1. Esto puede llevar a algunos equvocos, as que en este artculo asumiremos que las celdas, tanto en filas como en columnas, comienzan en 1. Ya tenemos la celda de la primera columna y la primera fila almacenada en la variable celda, y ahora podemos acceder a su valor:
>>> celda.setText(Hola) >>> print celda.text() Hola >>>
El objeto Cell, que no es otro que el que representan las celdas, puede almacenar dos tipos de datos diferentes. Tenemos el
54
Nmero 28
WWW.LINUX- MAGAZINE.ES
cargar y descargar scripts sin tener que cerrar Kspread. Para ello, slo tenemos que pulsar en el botn con la carpeta y seleccionar el script a cargar. Una vez cargado podemos ejecutarlo pulsando el botn de la rueda dentada. Para descargarlo debemos pulsar en el botn con la equis dentro de un crculo. La seccin Historial no es otra cosa que una lista con los ltimos scripts ejecutados. Podemos copiar el cdigo del Listado 1 y guardarlo en cualquier sitio (digamos /tmp) y cargarlo con el gestor de scripts de Kspread para probarlo. El resultado ser el que aparece en la Figura 2.
Un Generador de Facturas
Imaginemos que tenemos algn sistema que registra compras en una base de datos. Puede que sea una tienda online o un programa de algn tipo. Una vez que ya estn reflejadas las compras en la base de datos debemos generar las facturas. Existen muchos sistemas para hacer esto. Normalmente implican el empleo de alguna librera de generacin de ficheros PDF. El problema que surge es que las facturas generadas suelen ser bsicas
y esquemticas. Como cuando encontramos una web sin diseo, slo con lo bsico para poder ser llamada web. Todos los negocios quieren tener facturas impresionantes y profesionales con logotipos y buena tipografa. Existe otra posibilidad. Podemos hacer una plantilla de una factura, con logotipos y todo lo que el diseador quiera poner. Cuando tengamos que generar una factura cargaremos ese plantilla y rellenaremos los datos necesarios. Con Kspread, Postgresql, Python y Kross podemos hacer esto de forma muy sencilla y en pocas lneas de cdigo. Nuestro programa recopilar los datos de la base de datos Postgresql (podra ser Mysql o cualquier otra), cargar una plantilla en Kspread y la rellenar. Posteriormente guardar el fichero en disco duro y pasar a procesar la siguiente factura. Y todo esto con slo ejecutar un script!
mnimo razonable para poder trabajar. Usar la base de datos Postgresql porque es la que me gusta, no quiero entrar a discutir si es mejor o peor que otras porque aqu lo importante es Python ;). Para poder acceder a Postgresql necesitamos emplear alguna de las distintas libreras que existen. En mi caso emplear pgdb (ver [2]). Me gusta porque tiene pocas funciones y es muy bsica:
>>> con = pgdb.connectU (127.0.0.1:facturas) >>> facturas = con.cursor() >>> facturas.executeU (select id,nombre,U apellidos,fecha from facturas) >>> foreach factura inU facturas.fetchall(): >>> print factura[0] 1 2 3 >>> con.close()
La Base de Datos
Este ejemplo nicamente pretende ser ilustrativo, por lo que no voy a crear todo un sistema de facturacin. Pero s el
En este breve ejemplo podemos ver en funcionamiento todos los mtodos de pgdb que vamos a emplear. La idea es simple. Nos conectamos con la base de
Listado 2: kfactura.py
01 02 03 04 05 #!/usr/bin/env krossrunner import pgdb import krosskspreadcore con = pgdb.connect(127.0.0.1:factur as) 19 20 doc.openUrl(/tmp/factura.ots ) 21 22 23 24 25 26 27 nombre = factura[1]+ +factura[2] hoja = doc.currentSheet() escribe(hoja,2,8,nombre) escribe(hoja,6,3,str(factura[0 ])) 28 escribe(hoja,6,4,str(factura[3 ])) 29 30 31 32 33 # Buscamos sus artculos compras = con.cursor() compras.execute(select facturas.id,productos.descripc ion,facturas_productos.cantida d,productos.precio from facturas_productos,productos,f acturas where facturas.id=facturas_productos .factura and productos.id=facturas_producto s.producto and facturas.id=%s % (factura[0])) 34 fila = 17 35 for compra in compras.fetchall(): 36 escribe(hoja,1,fila,str(compra [2])) 37 escribe(hoja,2,fila,str(compra [1])) 38 escribe(hoja,5,fila,str(compra [3])) 39 escribe(hoja,6,fila,str(compra [2]*compra[3])) 40 fila += 1 41 42 doc.saveUrl(/tmp/factura-+st r(factura[0])+.ods) 43 44 con.close()
06 07 facturas = con.cursor() 08 09 facturas.execute(select id,nombre,apellidos,fecha from facturas) 10 11 def escribe (hoja, col,fila, valor): 12 celda = hoja.cell(col,fila) 13 celda.setText(valor) 14 15 doc = krosskspreadcore.get(KSpreadD ocument) 16 17 for factura in facturas.fetchall() : 18 # Nuevo KSpread
WWW.LINUX- MAGAZINE.ES
Nmero 28
55
datos, que aqu se encuentra en mi propio ordenador y se llama facturas. Creamos un cursor, que no es otra cosa que una conexin para poder realizar peticiones. Ejecutamos una consulta que no nos devuelve nada. El resultado de la consulta se queda en la base de datos hasta que nosotros lo recuperemos con fetchall(), que nos devuelve una lista de las filas devueltas. Al ser una lista podemos acceder a los campos de la fila devuelta usando la notacin normal de listas de Python. Cuando hayamos acabado cerramos la conexin y listo.
Nuestra Plantilla
La plantilla que emplearemos en nuestro ejemplo ha sido diseada sobre Kspread, aparece en la Figura 3. No tiene nada especial, es simplemente un fichero Kspread vaco. Lo creamos, le damos formato y lo guardamos en un directorio conocido. Es recomendable cambiar el formato de las celdas que vayamos a rellenar para que sean de texto y que el contenido se alinee con el fondo de la celda. De esta forma el texto saldr alineado de forma correcta con el texto que haya al lado. Adems, me gusta guardar este fichero como Template, plantilla, usando la terminacin ots. Una breve resea. A pesar de que se supone que tanto Koffice como OpenOffice usan el mismo formato para guardar los documentos, las pruebas que he realizado me demuestran que no son totalmente compatibles. El fichero de
plantilla que se ve en la Figura 3 cargado con OpenOffice muestra diferencias. La plantilla incorpora, aunque no pueda verse, unas cuantas frmulas, de forma que se calculen ciertos valores, por ejemplo el total a pagar.
asignada. Los ficheros resultantes se guardarn con formato ods. Podremos abrir estos ficheros con Koffice e imprimirlos o generar ficheros PDF. Por desgracia estas dos acciones an se encuentran fuera del alcance de Kross. Los ficheros tendrn el formato que aparece en la Figura 4.
Script Final
Conectaremos con la base de datos y nos traeremos las facturas existentes y pasaremos a conectar Kspread. Para cada factura cargaremos la plantilla de factura, nos traeremos los productos adquiridos y los pondremos en las celdas correspondientes. Cuando todos los datos estn cargados, guardaremos el fichero con un nombre que depender del nmero de factura que tenga
Conclusin
Los desarrolladores de Koffice no han querido introducir en Koffice un soporte completo para Kross debido a que est planeado para la versin 2.0, no para la actual, la 1.6. An as es posible realizar scripts realmente tiles. Kross nos permitir en KDE 4.0 programar scripts que afectarn a todos los componentes de KDE por lo que se abre muchas posibilidades para aquellos que quieren simplifiI car su trabajo.
RECURSOS
[1] http://kross.dipe.org/old/ kspreadscriptingbook/ [2] http://www.pygresql.org/
56
Nmero 28
WWW.LINUX- MAGAZINE.ES