Blog technique sur mes expériences de développeur.
7 décembre 2011
Il y a quelque temps, j’ai travaillé sur un projet Perl 5 qui consistait à manipuler des fichiers Excel via les modules CPAN Spreadsheet::ParseExcel et Spreadsheet::WriteExcel.
Ce projet consistait à recopier certaines cellules d’un fichier A vers un fichier B en conservant le format de celles-ci.
Mon premier réflexe a été d’appliquer le format de la cellule que je recopie à la cellule dans laquelle j’écris. Ce qui donne :
#!/usr/bin/perl -w
use strict;
use Spreadsheet::ParseExcel;
use Spreadsheet::WriteExcel;
#Lecture
my $parser = Spreadsheet::ParseExcel->new();
my $xls_r = $parser->parse('fichierA.xls');
#Ecriture
my $xls_w = Spreadsheet::WriteExcel->new('fichierB.xls');
my $worksheet_w = $xls_w->add_worksheet();
#Vérification
if ( !defined $xls_r ) {
die $parser->error() . "\n";
}
#valeurs min/max
my ( $row_min, $row_max ) = (0, 54);
my ( $col_min, $col_max ) = (0, 23);
#traitement
my $worksheet_r = $xls_r->worksheet(0);
for my $col ( $col_min .. $col_max ) {
for my $row ( $row_min .. $row_max ) {
my $cell = $worksheet_r->get_cell( $row, 0);
next unless $cell;
#On récupère le format
my $format = $cell->get_format();
#On écrit
$worksheet_w->write($row, 0, $cell->value(), %$format);
}
}
Oui mais voilà, si le contenu des cellules est bien recopié, le format lui n’est absolument pas conservé… Et pour cause ! Entre les modules CPAN Spreadsheet::ParseExcel et Spreadsheet::WriteExcel le format n’est pas du tout exprimé de la même façon !
La solution est donc de convertir le format à la main !
Voici les morceaux de script qui permettent de faire ça, propriété par propriété.
#Font
if(my $font = $format_r->{Font}) {
$format_w->set_font($font->{Name});
$format_w->set_bold($font->{Bold});
$format_w->set_italic($font->{Italic});
$format_w->set_size($font->{Height});
$format_w->set_underline($font->{UnderlineStyle});
$format_w->set_color($font->{Color});
$format_w->set_font_strikeout($font->{Strikeout});
$format_w->set_font_script($font->{Super});
}
#Protection
$format_w->set_locked($format_r->{Lock});
$format_w->set_hidden($format_r->{Hidden});
#Alignment
my $alignH = $format_r->{AlignH};
if($alignH == 1) {
$format_w->set_align('left');
}
elsif($alignH == 2) {
$format_w->set_align('center');
}
elsif($alignH == 3) {
$format_w->set_align('right');
}
elsif($alignH == 4) {
$format_w->set_align('fill');
}
elsif($alignH == 5) {
$format_w->set_align('justify');
}
elsif($alignH == 6) {
$format_w->set_align('center_across');
}
#AlignmentV
my $alignV = $format_r->{AlignV};
if($alignV == 0) {
$format_w->set_align('top');
}
elsif($alignV == 1) {
$format_w->set_align('vcenter');
}
elsif($alignV == 2) {
$format_w->set_align('bottom');
}
elsif($alignV == 3) {
$format_w->set_align('vjustify');
}
#Fill
if(my $fill = $format_r->{Fill}) {
$format_w->set_pattern(@$fill[0]);
$format_w->set_fg_color(@$fill[1]);
$format_w->set_bg_color(@$fill[2]);
}
#Border style
if(my $borderStyle = $format_r->{BdrStyle}) {
$format_w->set_left(@$borderStyle[0]);
$format_w->set_right(@$borderStyle[1]);
$format_w->set_top(@$borderStyle[2]);
$format_w->set_bottom(@$borderStyle[3]);
}
#Border color
if(my $borderColor = $format_r->{BdrColor}) {
$format_w->set_left_color(@$borderColor[0]);
$format_w->set_right_color(@$borderColor[1]);
$format_w->set_top_color(@$borderColor[2]);
$format_w->set_bottom_color(@$borderColor[3]);
}
#Diagonal Cell Borders
if(my $borderDiag = $format_r->{BdrDiag}) {
$format_w->set_format_properties(diag_type => @$borderDiag[0], diag_border => @$borderDiag[1], diag_color => @$borderDiag[2],);
}
#Le reste
$format_w->set_indent($format_r->{Indent});
$format_w->set_text_wrap($format_r->{Wrap});
$format_w->set_shrink($format_r->{Shrink});
$format_w->set_rotation($format_r->{Rotate});
$format_w->set_text_justlast($format_r->{JustLast});
Vous êtes maintenant en mesure d’exploiter correctement le style de vos cellules Excel !