• Publicidad

Leer csv y guardar en un Excel

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Leer csv y guardar en un Excel

Notapor stevnet » 2017-09-26 14:18 @637

Estimados, buenas tardes.

Me estoy interiorizando de a poco en este lenguaje, he leído alguno de sus mensajes de ustedes buscando alguna ayuda a mi problema...

Básicamente lo que necesito hacer es leer un fichero CSV, que lo recorra completo y que guarde los datos en un archivo Excel.

Agradecería desde ya me pudieran compartir un ejemplo a fin de modificarlo a mis necesidades.

Desde ya, ¡gracias!

¡Saludos! :wink:
stevnet
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2017-09-26 14:14 @635

Publicidad

Re: Leer csv y guardar en un Excel

Notapor explorer » 2017-09-26 15:34 @690

JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Leer csv y guardar en un Excel

Notapor stevnet » 2017-09-27 12:54 @579

Hola, explorer.

Te cuento que lamentablemente no pude conseguir lo que buscaba, pero te cuento que estoy usando la librería Win32::OLE, en donde hice la siguiente subrutina (leer_workbook) para leer un archivo Excel que apunto desde un panel inicial.

La idea es que cuando obtenga el CSV final, esta información se me guarde en el archivo Excel que apunto en el inicio.

sub leer_workbook{
my ($ExcelApp, $xls_file) = @_;
my $Book = $ExcelApp->Workbooks->Open("$xls_file") or die "No se pudo abrir $xls_file";
($Book);
}

De esta forma estoy leyendo el fichero CSV:

while (<CSV>) {
chomp;
s/\s+//g;
my ($SOURCE, $REGION, $CATEG, $PRODUCT, $CUTOFF) = split(",", $_);
my $dia;

$datos{$dia} = $TOTAL_MASS;
}

close CSV;

%datos;
}

Y de esta forma estoy guardando la información en mi archivo Excel:

my $ExcelApp = Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application', 'Quit');

$ExcelApp->{DisplayAlerts} = 0;

$ExcelApp->{Visible} = 0;

my $Book;

$Book = leer_workbook $ExcelApp, $archivo_excel;

my $Sheet = $Book->Worksheets(1);

for my $dia (sort{$a <=> $b} keys %datos){
$Sheet->Cells($fila , $col)->{NumberFormat} = "0.00";
$Sheet->Cells($fila , $col)->{Value} = $datos{$dia};
}

Todo lo anterior anda bien, pero lo que busco es guardar todo el contenido del CSV en mi archivo Excel, y no por parte o columnas... ¿¿se entiende?? Necesito ver la forma de recorrer todo el CSV y que se guarde íntegramente en mi archivo Excel.

Desde ya se agradece todo el apoyo.

Saludos.
stevnet
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2017-09-26 14:14 @635

Re: Leer csv y guardar en un Excel

Notapor explorer » 2017-09-27 15:47 @699

Yo haría lo siguiente (a grandes rasgos).
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Inicio la apertura del Excel.

my $fila = 1;

Inicio la apertura del archivo CSV.

Recorro todos los registros del archivo CSV.

Para cada uno de esos registros, hago un split "," y guardo todos los campos en un array:

my @campos = split ",";

Guardo los @campos en la línea de la hoja Excel:

my $columna = 1;
for my $campo (@campos) {
    $Sheet->Cell($fila, $columna)->{Value} = $campo;
    $columna++;
}

Preparo la siguiente fila:

$fila++;

y repito el bucle de registros.

Finalmente, guardo la hoja.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Ahora bien... hay otra forma más drástica.

Como estás usando el protocolo OLE, eso significa que estás dialogando de forma "directa" con el propio Excel... por lo que puedes pedirle a Excel... que sea él el que abra el archivo CSV directamente, es decir, como si estuviéramos abriendo un archivo XLS normal.

Yo estoy seguro que Excel es capaz de abrir un archivo CSV sin problemas (salvo que haya problemas con la codificación de caracteres, los caracteres de fin de línea y si algún campo contiene caracteres incompatibles con la norma CSV).

Una vez que Excel ha leído el archivo CSV, ahora le pedimos que... lo guarde con el formato que queramos.

$Sheet->SaveAs("NEWFILENAME.XLS", xlExcel8);

# Lista de formatos en https://msdn.microsoft.com/en-us/librar ... ormat.aspx

Esto es tan común que existe un módulo que ya lo hace: Win32::Scsv Puedes mirarle el código para ver cómo lo hace, en caso de que no quieras instalarlo. Pero bastaría con una línea así:

csv_2_xls('dummy.csv' => 'Test2.xls');

Pero incluso permite hacer alguna transformación:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. csv_2_xls('dummy.csv' => 'New.xlsx%Tab9', {
  2.   'tpl'  => 'Template.xls',
  3.   'prot' => 1,
  4.   'csz'  => [
  5.      ['H:H' => 13.71],
  6.      ['A:D' => 3],
  7.   ],
  8.   'fmt'  => [
  9.      ['A:A' => '#,##0.000'],
  10.      ['B:B' => '\\<@\\>'],
  11.      ['C:C' => 'dd/mm/yyyy hh:mm:ss'],
  12.   ],
  13. });
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

En el código fuente de este módulo, al principio, verás que usa los valores numéricos para el método SaveAs.

Naturalmente, esto solo sirve si queremos convertir un CSV a XLS. Si nuestra idea es "meter" el CSV en una de las hojas del libro Excel, entonces sí que debemos hacerlo con el procedimiento anterior.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Leer csv y guardar en un Excel

Notapor stevnet » 2017-09-28 11:04 @502

Gracias, explorer, por responder tan rápido.

Respecto a tu forma "drástica", te cuento que no tengo ese módulo instalado, puesto que estoy usando una aplicación que sólo interpreta lenguaje Perl, el cual no trae todos los módulos.

En relación a tu primera respuesta, coincidimos en lo que se debería hacer, pero estoy recién empezando en este lenguaje y no logro hacer aún algunas cosas por si solo, particularmente el tema de "recorrer todos los registros del archivo CSV", ya que el archivo ya existe, técnicamente no sé cómo asociarlo a un array, siempre he visto arrays de esta forma:

my @datos = [[79899,34567,2500,0.23],
[79899,34567,2501,0.34],
[79222,34222,2501,0.2]];

Pero en este caso debe tomar los registros del CSV ya existente.

Puntualmente me gustaría que me pudieras poner algún ejemplo de cómo recorrer y tomar los valores de un archivo CSV que ya existe y alojarlos en un array para así adaptarlo a mis necesidades ¡por favor!

Desde ya, gracias. ¡Saludos!
stevnet
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2017-09-26 14:14 @635

Re: Leer csv y guardar en un Excel

Notapor explorer » 2017-09-28 19:06 @837

stevnet escribiste:Respecto a tu forma "drástica", te cuento que no tengo ese módulo instalado, puesto que estoy usando una aplicación que sólo interpreta lenguaje Perl, el cual no trae todos los módulos.
Pues es muy raro lo que dices, porque Win32::OLE no viene en la distribución básica de Perl. De todas maneras, puedes ver su código por si quieres ver cómo hace el proceso.

stevnet escribiste:En relación a tu primera respuesta, coincidimos en lo que se debería hacer, pero estoy recién empezando en este lenguaje y no logro hacer aún algunas cosas por si solo, particularmente el tema de "recorrer todos los registros del archivo CSV", ya que el archivo ya existe, técnicamente no sé cómo asociarlo a un array.
Pero si tu mismo lo has escrito, en el mensaje anterior:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while (<CSV>) {                         # recorrer todos los registros del archivo CSV
  2.         chomp;                                                          # quitar fin de línea
  3.         s/\s+//g;                                                       # quitar espacios en blanco
  4.         my @campos = split ",";                                         # dividir usando las comas como separador
  5.  
  6.         my $columna = 1;                                                # índice de la primera columna
  7.         for my $campo (@campos) {                                       # para todos los campos leídos antes
  8.                 $Sheet->Cell($fila, $columna)->{Value} = $campo;                # lo guardamos en la hoja
  9.                 $columna++;                                                     # apuntamos a siguiente columna
  10.         }
  11. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 20 invitados