2009-01-16 11 views
26

Así que tenemos esta aplicación web donde admitimos datos UTF8. Hooray UTF8. Y podemos exportar los datos suministrados por el usuario a CSV sin ningún problema, todavía está en UTF8 en ese punto. El problema es cuando abre un CSV UTF8 típico en Excel, lo lee como texto codificado ANSII, y en consecuencia trata de leer caracteres de dos bytes como ø y ü como dos caracteres separados y termina con falla.¿Cuál es la mejor manera de exportar datos UTF8 a Excel?

Así que he hecho un poco de excavación (la gente de Intervals tiene una publicación interesante about it here), y hay algunas opciones limitadas aunque ridículamente molestas por ahí. Entre ellos:

  • suministrar un archivo UTF-16 Little Endian TSV, que Excel interpretará correctamente, pero que no apoyará los datos multilínea
  • que suministran los datos en una tabla HTML con un tipo MIME de Excel o extensión de archivo (no estoy seguro si esta opción es compatible con UTF8)
  • Hay tres o cuatro formas de obtener datos XML en las diversas versiones recientes de Excel, y eso sería compatible con UTF8, en teoría. SpreadsheetML, utilizando XSLT personalizado o generando el nuevo formato XML de Excel mediante plantillas.

Parece que no importa qué, probablemente voy a querer continuar ofreciendo un archivo CSV sencillo para las personas que no lo usan para Excel de todos modos, y una opción de descarga por separado para Excel.

¿Cuál es la forma más sencilla de generar ese archivo Just-For-Excel que admitirá correctamente UTF8, mi querido Stack Overflowers? Si la opción más simple solo admite la última versión de Excel, eso sigue siendo interesante.

Estoy haciendo esto en una pila de Rails, pero es curioso cómo los .Neters y gente de cualquier framework manejan esto. Trabajo en algunos entornos diferentes y definitivamente este es un problema que volverá a surgir.

Actualización 2010-10-22: Nos había estado utilizando la gema Ruport en nuestro sistema de seguimiento de tiempo para proporcionar Tempo las exportaciones CSV cuando por primera vez esta pregunta. Uno de mis compañeros de trabajo, Erik Hollensbee, lanzaron conjuntamente un filtro rápido para Ruport que nos proporcione salida real Excel XSL, y pensé que me gustaría compartir aquí que para cualquier otro rubí-tas:

require 'rubygems' 
require 'ruport' 
require 'spreadsheet' 
require 'stringio' 

Spreadsheet.client_encoding = "UTF-8" 

include Ruport::Data 

class Ruport::Formatter::Excel < Ruport::Formatter 
    renders :excel, :for => Ruport::Controller::Table 

    def output 
    retval = StringIO.new 

    if options.workbook 
     book = options.workbook 
    else 
     book = Spreadsheet::Workbook.new 
    end 

    if options.worksheet_name 
     book_args = { :name => options.worksheet_name } 
    else 
     book_args = { } 
    end 

    sheet = book.create_worksheet(book_args) 

    offset = 0 

    if options.show_table_headers 
     sheet.row(0).default_format = Spreadsheet::Format.new(
     options.format_options || 
     { 
      :color => :blue, 
      :weight => :bold, 
      :size => 18 
     } 
    ) 
     sheet.row(0).replace data.column_names 
     offset = 1 
    end 

    data.data.each_with_index do |row, i| 
     sheet.row(i+offset).replace row.attributes.map { |x| row.data[x] } 
    end 

    book.write retval 
    retval.seek(0) 
    return retval.read 
    end 
end 

Respuesta

5

Eres olvidando crear un origen de datos OleDB e Interoperación de Excel, pero también hay problemas con ellos.

Recomiendo la opción SpreadsheetML. Funciona bastante bien, es probable que su plataforma tenga algunas herramientas decentes para compilar archivos xml, y es totalmente compatible desde OfficeXP. Office2000 no es compatible, pero la experiencia personal es que funciona de manera limitada.

+0

"Te estás olvidando ... un OleDB ..." Ssh! Este es un entorno Unix, así que me gustaría evitar ese tipo de Voodoo. ¡Gracias por el consejo! –

+1

¿por qué está marcado como correcto? – hoju

+0

@Richard: debido al segundo párrafo, que no depende de oledb. Aunque a partir de la actualización que se publicó más de 1 1/2 años después, debería haber una respuesta aquí señalando a la gente a Ruby Rupert. –

1

Si crea un archivo XML con la codificación UTF y guardarlo como un .xls se abrirá incluso los caracteres de dos bytes:

xml version = "1.0" encoding = "UTF-8"

+0

Intenté simplemente guardar un documento XML de datos tabulares con la extensión .xls y luego lo abrí con Excel para Mac 2003 y simplemente se acumuló en él. Y una gran cantidad de nuestros usuarios son personas de Mac. –

+1

Nunca lo he intentado con MAC, pero se supone que debe funcionar, XML es un estándar – Rulas

+0

@BillyGray ¿qué tipo de error es 'barfed'? – gcb

1

Tuve exactamente el mismo problema de enviar datos UTF8 a Excel. Mi solución:

La versión actual de Perl Spreadsheet :: WriteExcel código cpan escribe correctamente archivos de Excel utilizando datos UTF8.

Así que escribí un plugin que Rieles a) abre un tubo de dos vías para un programa Perl b) envía los datos, una fila a la vez, con el programa de Perl. Yo uso Yaml como el formato de datos del mensaje. (Estándar de Ruby yaml no es UTF-8, hay una versión especial disponible, ya2yaml) c) El programa Perl crea el archivo de Excel d) Cuando el programa rieles indica (a través de un mensaje yaml) que la última fila ha sido enviado, el Perl programa crea el archivo de Excel y envía el estado nuevamente al programa de rieles.

Por supuesto, la adición de un programa de perl para un proyecto de carriles a través de un proceso paralelo y un tubo es en gran medida en el espectro de "ingeniería" en lugar de "Computer Science". (Hace el trabajo, pero no es elegante.) Pero funciona bien y me ahorró las semanas que tardaría en llevar el código WriteExcel a Ruby. También tenga en cuenta que el puerto Ruby actualmente disponible de WriteExcel no maneja utf8.

Mi sw es de código abierto permisiva, pero no he tenido tiempo de liberación todavía. Si lo quiere en su estado actual, vea http://sandbox.kluger.com/write_excel_v.5.tar

Tenga en cuenta que usted querrá crear sus archivos de Excel en un proceso en segundo plano, no en el proceso del controlador de Rails ya que bloquearía a otros clientes del navegador produciendo el archivo excel Uso el complemento DelayedJob, funciona bien.

Espero que esto ayude,

Larry

+0

Eso es un gran consejo, muchas gracias, Larry ;-) –

-3

Trate OpenOffice Calc - es mucho más amigable Unicode - ambos archivos CSV Importación y exportación con codificación UTF-8.

+3

La pregunta era acerca de cómo exportar estos datos desde una aplicación web de tal manera que los usuarios puedan abrirlo en Excel. Probablemente no funcione para decirles a todos sus clientes que utilicen OpenOffice. – vezult

+0

Para ser justos, el póster es correcto en cuanto a que OpenOffice es más amigable para Unicode que Excel. Vine aquí buscando una forma de hacer esto usando Excel porque ya no quiero usar OpenOffice. – NielW

7

Después de luchar con el mismo problema durante unas horas me encontré con este excelente post sobre el tema

http://blog.plataformatec.com.br/2009/09/exporting-data-to-csv-and-excel-in-your-rails-app/ cita:

tanto, estas son las tres reglas para se ocupan de Excel-amigable -CSV:

  1. Use tabulaciones, no comas.
  2. Los campos NO deben contener líneas nuevas.
  3. Uso UTF-16 Little Endian para enviar el archivo al usuario. E incluya un Little Endian BOM manualmente.

Sin embargo, si usted está utilizando rubí, que problema se resuelve: primer lugar tiene la FasterCSV joya

pero terminé usando la gema hoja de cálculo que genera directamente las hojas de cálculo Excell (tengo limitación de enlaces, solo google spreadsheet + rubyforge) Brilliant!

-1

Excel no manejar UTF-8 correctamente. Se debe utilizar en lugar de una página de códigos que satisfacen sus necesidades

Response.ContentType = "text/plain"; 
// codepage: 28591, codepage name:iso-8859-1, codepage display name: Western European (ISO) 
Response.ContentEncoding = System.Text.Encoding.GetEncoding(28591); 
+0

Parece que funciona bien para mí, siempre que agregue una firma UTF8/BOM (EF BB BF). –

8

He descubierto que si se establece la codificación de juego de caracteres de la página Web para UTF-8, y luego de respuesta.BinaryWrite la marca de orden de bytes UTF-8 (0xEF 0xBB 0xBF) en la parte superior del archivo csv, luego Excel 2007 (no estoy seguro acerca de otras versiones) lo reconocerá como utf-8 y lo abrirá correctamente.

+0

He publicado un código que hace esto aquí - http://stackoverflow.com/a/9907364/150342 – Colin

1

Me enamoré de esta publicación en busca de la respuesta de Ruby al por qué Excel no cargaría correctamente una CSV con caracteres utf-8. Después de buscar alrededor y experimentar esta solución funcionó para mí:

csv_content = CSV.generate(col_sep: "\t", headers: :first_row, encoding: 'utf-8') do |csv| 
    csv << ["header1", "header2"] 
    csv << ["content1", "content2"] 
end 
write_content = Iconv.conv("utf-16le", "utf-8", "\xEF\xBB\xBF") 
write_content += Iconv.conv("utf-16le", "utf-8", csv_content) 
File.open("listing.csv", 'wb') {|f| f.write(write_content) } 
Cuestiones relacionadas