Exportar a XLS desde Rails

Hace unos días veíamos cómo exportar datos de una aplicación Ruby on Rails en formato CSV, y hoy vamos a ver cómo hacer para generar directamente un archivo de Excel. Una de las ventajas que tiene el formato XLS sobre CSV es la posibilidad de incluir varias hojas dentro de un mismo archivo.

En primer lugar, necesitaremos instalar la gema spreadsheet-excel. Aunque actualmente está en versión pre-alpha, a mí me ha funcionado estupendamente. Para ello la instalaremos usando gem, en mi caso desde Ubuntu GNU/Linux:

  1. jaime@zimpa:~$ sudo gem install spreadsheet-excel
  2. Password:
  3. Need to update 6 gems from http://gems.rubyforge.org
  4. ……
  5. complete
  6. Successfully installed spreadsheet-excel-0.3.5.1
  7. Installing ri documentation for spreadsheet-excel-0.3.5.1
  8. Installing RDoc documentation for spreadsheet-excel-0.3.5.1

Una vez disponible esta gema en nuestro sistema ya podemos usarla desde nuestro controlador:

  1. class ExportadorController < ApplicationController
  2.   require ’spreadsheet/excel’
  3.   include Spreadsheet
  4.   def xls
  5.     # Creamos un nuevo archivo Excel en disco
  6.     workbook = Excel.new("#{RAILS_ROOT}/public/xls/datos.xls")
  7.     # Añadimos hoja EMPRESAS
  8.     hoja_empresas = workbook.add_worksheet("Empresas")
  9.     # Fila de cabecera
  10.     @cabecera = %w(id nombre localidad provincia)
  11.     columna = 0
  12.     @cabecera.each do |cab|
  13.       hoja_empresas.write(0,columna,cab)
  14.       columna += 1
  15.     end
  16.     # Una fila para cada empresa
  17.     @empresas = Empresa.find(:all)
  18.     fila = 1
  19.     for e in @empresas
  20.       # Añado la fila con los datos en sus respectivas columnas
  21.       hoja_empresas.write(fila,0,e.id)
  22.       hoja_empresas.write(fila,1,e.nombre)
  23.       hoja_empresas.write(fila,2,e.localidad)
  24.       hoja_empresas.write(fila,3,e.provincia)
  25.       # Pasamos a la siguiente empresa en una nueva fila
  26.       fila += 1
  27.     end
  28.     # Añadimos hoja PRODUCTOS
  29.     hoja_productos = workbook.add_worksheet("Productos")
  30.     hoja_productos.write(0,0,"Datos de los productos…")
  31.     # Cerramos el libro
  32.     workbook.close
  33.     # Enviamos el fichero al navegador
  34.     send_file "#{RAILS_ROOT}/public/xls/datos.xls"
  35.   end
  36. end

En este ejemplo, hemos creado un archivo Excel (workbook) con dos hojas (worksheets), una con los datos de las empresas y otra para los productos (con un par de frases). El archivo se guardará en /public/xls y después se enviará al navegador con send_file.

Un tema importante a tener en cuenta es la codificación de caracteres. Si nuestros datos contienen tildes, eñes, etc., tenemos que asegurarnos de convertirlos a la hora de incorporarlos al Excel, para que se vean correctamente. Haremos esto con iconv, por ejemplo, en lugar de almacenar directamente el nombre, podemos hacerlo convirtiendo a otra codificación así:

  1. # En lugar de…
  2. # hoja_empresas.write(fila,1,e.nombre)
  3. # …usaremos…
  4. hoja_empresas.write(fila,1,Iconv.conv("ISO-8859-1","UTF-8", e.nombre))

2 comments ↓

#1 Héctor on 04.21.07 at 3:07 pm

Hola Jaime,

Creo que tengo bien instalada la gema (al menos con gem list sí aparece), pero al hacer workbook.close me da el siguiente error:

Errno::ENOENT in HomeController#pr_xls
No such file or directory -public/xls/datos.xls

¿Sabes que puede pasar? Gracias.

#2 Héctor on 04.21.07 at 3:14 pm

Me contesto yo mismo:
Hay q crear el directorio xls!

Saludos ;)

Leave a Comment