IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Conversion d'un fichier Excel en page (X)HTML


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 8
    Par défaut Conversion d'un fichier Excel en page (X)HTML
    Bonjour à tous,
    Je viens de développer un petit script permettant de convertir un fichier Excel (.xls donc antérieur à Office 2007) en page (X)HTML, et plus précisément en tableau.
    J'espère que cela intéressera du monde !
    Je me suis efforcé de mettre les commentaires en anglais pour qu'il soit utilisable et compréhensible par n'importe qui, désolé pour les francophones qui ont du mal avec la langue de Shakespeare
    C'est un don à la communauté, vous pouvez le modifier à votre guise.
    Si vous avez la moindre question, n'hésitez pas à me la poser ici.
    Fichiers attachés Fichiers attachés

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Une suggestion d'évolution de l'option -n : accepter une liste de numéro de feuille au lieu d'un nombre de feuille. Exemples :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    xls2html -n 1,2 file.xls file.html; # feuilles 1 et 2
    xls2html -n 1..3,5 file.xls file.html; # feuilles 1 à 3 et 5
    xls2html -n 2.. file.xls file.html; # toutes les feuilles à partir de la 2e
    xls2html -n ..4 file.xls file.html; # les 4 premières feuilles
    xls2html -n -1 file.xls file.html; # la dernière feuille

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 8
    Par défaut
    Très bonne idée, merci !
    J'ai un peu bataillé avec les expressions régulières mais j'ai fini par y arriver (peut-être pas la façon la plus élégante ni la plus rapide, mais ça marche), j'ai du coup mis à jour le premier post du sujet pour y inclure la version mise à jour du script.

  4. #4
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    J'y jetterais un coup d'oeil et le placerait dans les sources de la rubrique Perl.

    Bon sinon, à première vu. Pour l'améliorer, faudrait utiliser XML::Writer. C'est plus propre pour la création de fichier balisé.
    Ensuite, après une première indentation du code, on obtient un programme plus compact et lisible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    #!/usr/bin/perl 
    #~
    #~ Copyleft 2010 VelC.
    #~ This program is free software; you can redistribute it and/or
    #~ modify it under the same terms as Perl itself.
    #~
    #~ This program was originally written in french, therefore a lot of
    #~ variables have french names. Do not hesitate to change them if you
    #~ like.
    #~
    #~ For the CSS I choose to write it directly in each markup. That's
    #~ ugly and usually to ban but it was much more easier for me to do
    #~ so, since I don't know which cells have the same style, and so
    #~ which cells should have the same class.
    #~
    #~ This program was encoded in ISO-8859-1 (Western), so that it could
    #~ produce HTML files encoded in ISO-8859-1, as written in the header
    #~ I wrote. To change this, simply copy-paste the source code in a
    #~ UTF-8 file (for example) and change the HTML charset at line 199
    #~ (look for "charset" in the file and you'll find the relevant line).
    #~
    #~ See http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel-0.57/lib/Spreadsheet/ParseExcel.pm
    #~ for further details about the possibilities of SpreadSheet:ParseExcel
    #~
     
    use strict;
    use Spreadsheet::ParseExcel qw (new Parse worksheets);
    use Getopt::Std;
    use Encode;
    use File::Basename;
     
    #~ The -s option define the normal font-size used in the page. For
    #~ example, -s 10 will define that the Excel font-size 10 equals 1em,
    #~ and thus that a font-size equals to 12 will be represented by 1.2em.
    #~ If left empty, the normal font-size will be 14.
     
    #~ The -n option define the sheets that must be treated. If left empty
    #~ or equals to zero, all sheets will be treated. If this value
    #~ contains greater numbers than the real number of sheets in the
    #~ Excel File, these numbers will be ignored. The first sheet is
    #~ the sheet 1 and not 0.
     
    #~ xls2html -n 1,2 file.xls file.html; # feuilles 1 et 2
    #~ xls2html -n 1..3,5 file.xls file.html; # feuilles 1 à 3 et 5
    #~ xls2html -n 2.. file.xls file.html; # toutes les feuilles à partir de la 2e
    #~ xls2html -n ..4 file.xls file.html; # les 4 premières feuilles
    #~ xls2html -n -1 file.xls file.html; # la dernière feuille
     
    #~ xls2html -n 1,2 file.xls file.html; # sheets 1 and 2
    #~ xls2html -n 1..3,5 file.xls file.html; # sheets 1 to 3 and 5
    #~ xls2html -n 2.. file.xls file.html; # every sheets from 2nd
    #~ xls2html -n ..4 file.xls file.html; # sheets 1 to 4
    #~ xls2html -n -1 file.xls file.html; # last sheet
     
    our ( $opt_s, $opt_n );
    getopts("s:n:");
     
    my $nbarg = @ARGV;
    ( $nbarg == 2 ) || die "Usage : xls2html.pl [-s number][-n number] File_in.xls File_out.html\n";
    my $fileIn = shift;
    ( $fileIn =~ /^.*\.xls$/ ) || die "Usage : xls2html.pl [-s number][-n number] File_in.xls File_out.html\n";
    my $fileOut       = shift;
    my $fileOutSuffix = '';
    if ( $fileOut =~ /^(.*)\.(html)$/ || $fileOut =~ /^(.*)\.(htm)$/ ) {
      $fileOut       = $1;
      $fileOutSuffix = $2;
    }
    else {
      die "Usage : xls2html.pl [-s number][-n number] File_in.xls File_out.html\n";
    }
     
    my $normal_size = 10;
    my @n_sheets;
    my $nb_sheets    = 0;
    my $parser       = Spreadsheet::ParseExcel->new();
    my $workbook     = $parser->parse($fileIn);
    my @worksheets   = $workbook->worksheets();
    my $sheets_count = $workbook->worksheet_count();
     
    if ( defined($opt_s) ) {
      ( $opt_s =~ /^(\d+\.?\d*|\.\d+)$/ && $opt_s > 0 && $opt_s < 100 )
        || die "The -s option has to be followed by a valid number !";
      $normal_size = $opt_s;
    }
     
    if ( defined($opt_n) ) {
      for ( my $i = 0; $i < $sheets_count; $i++ ) {
        $n_sheets[$i] = 0;
      }
     
      my @regtab;
      my $i = 0;
     
      while ( $opt_n =~ /(^\.\.\d+)|(\d+\.\.$)|(\d+\.\.\d+)|(\d+)|,/g ) {
        $regtab[ $i++ ] = $&;
      }
     
      if (@regtab) {
        for ( my $j = 0; $j < $i; $j++ ) {
          if ( $regtab[$j] =~ /^\.\.(\d+)$/ ) {
            for ( my $k = 0; $k < $1; $k++ ) {
              $n_sheets[$k] = 1;
            }
            $nb_sheets += $1;
          }
          elsif ( $regtab[$j] =~ /^(\d+)\.\.$/ ) {
            for ( my $k = $1 - 1; $k < $sheets_count; $k++ ) {
              $n_sheets[$k] = 1;
            }
            $nb_sheets += $sheets_count - $1 + 1;
          }
          elsif ( $regtab[$j] =~ /^(\d+)\.\.(\d+)$/ ) {
            for ( my $k = $1 - 1; $k < $2; $k++ ) {
              $n_sheets[$k] = 1;
            }
            $nb_sheets += $2 - $1 + 1;
          }
          elsif ( $regtab[$j] =~ /^(\d+)$/ ) {
            $n_sheets[ $1 - 1 ] = 1;
            $nb_sheets++;
          }
          elsif ( $regtab[$j] =~ /^,$/ ) {
     
            #~ does nothing, but ',' is a correct value
          }
          else {
            die "An error occured, incorrect option -n.";
          }
     
        }
      }
      else {
        die "The -n option has to be followed by a valid format ! Example : ..2,4,6..8,10..";
      }
    }
    else {
      for ( my $i = 0; $i < $sheets_count; $i++ ) {
        $n_sheets[$i] = 1;
        $nb_sheets++;
      }
    }
     
    my $filename;
    my $worksheet;
     
    for ( my $k = 0; $k < $sheets_count; $k++ ) {
      if ( $n_sheets[$k] ) {
        $worksheet = $workbook->worksheet($k);
        my $ligmax = $worksheet->row_range();
        my $colmax = $worksheet->col_range();
     
        if ( $fileIn =~ /^(.*)\.xls$/ && $nb_sheets == 1 ) {
          $filename = $1;
        }
        else {
          $filename = $worksheet->get_name();
        }
     
        #~ File where to write the result
        #~ If there's only one sheet to produce, the name of this sheet
        #~ isn't include in the name of the output file. Otherwise, it is
        #~ for each produced sheet.
        if ( $nb_sheets == 1 ) {
          open( FO, '>' . $fileOut . '.' . $fileOutSuffix ) || die "Cannot open file: $!\n";
        }
        else {
          open( FO, '>' . $fileOut . '-' . $filename . '.' . $fileOutSuffix ) || die "Cannot open file: $!\n";
        }
     
        #~ Beginning of the HTML file
        print FO
          '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
          . "\n"
          . '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" >' . "\n"
          . '	<head>' . "\n"
          . '		<title>'
          . $filename
          . '</title>' . "\n"
          . '		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />' . "\n"
          . '	</head>' . "\n"
          . '	<body>' . "\n"
          . '		<table>' . "\n";
     
    #~ Iteration on each line and each column of the worksheet, writing down each cell from left to right and from top to bottom
     
        my $bloc  = '';
        my @cells = $worksheet->{Cells};
        for ( my $i = 0; $i <= $ligmax; $i++ ) {
          print FO "			<tr>\n";
          for ( my $j = 0; $j <= $colmax; $j++ ) {
            my $cell = $cells[0][$i][$j];
            if ( defined($cell) ) {
              my $contenu = $cell->value();
              my $format  = $cell->get_format();
              my $gras;
              if ( $format->{Font}->{Bold} ) {
                $gras = "bold";
              }
              else {
                $gras = "normal";
              }
              my $italique;
              if ( $format->{Font}->{Italic} ) {
                $italique = "italic";
              }
              else {
                $italique = "normal";
              }
              my %font = (
                "nom"      => $format->{Font}->{Name},
                "gras"     => $gras,
                "italique" => $italique,
                "taille"   => $format->{Font}->{Height},
                "couleur"  => $format->{Font}->{Color}
              );
              my $alignH = $format->{AlignH};
     
              #~ 0 => No alignment
              #~ 1 => Left
              #~ 2 => Center
              #~ 3 => Right
              #~ 4 => Fill
              #~ 5 => Justify
              #~ 6 => Center across
              #~ 7 => Distributed/Equal spaced
     
              if ( $alignH == 3 ) {
                $alignH = "right";
              }
              elsif ( $alignH == 2 || $alignH == 6 ) {
                $alignH = "center";
              }
              elsif ( $alignH == 5 || $alignH == 4 ) {
                $alignH = "justify";
              }
              else {
                $alignH = "left";
              }
              my @fill    = $format->{Fill};
              my $couleur = $parser->ColorIdxToRGB( $fill[0][1] );
              print FO '				<td style="font-family:'
                . $font{"nom"} . ';'
                . 'font-size:'
                . ( $font{"taille"} / $normal_size ) . 'em;'
                . 'color:'
                . $font{"couleur"} . ';'
                . 'font-weight:'
                . $font{"gras"} . ';'
                . 'font-style:'
                . $font{"italic"} . ';'
                . 'text-align:'
                . $alignH . ';'
                . 'background:#'
                . $couleur . ';' . '">' . "\n";
              print FO '					' . $contenu . "\n";
              print FO "				</td>\n";
            }
          }
          print FO "			</tr>\n";
        }
     
        print FO "	</body>\n</html>";
     
        close FO || die "An error while closing $fileIn\n";
      }
    }
    print "\nHTML successfully generated !\n";
    Je le teste ce soir si j'ai du temps. Merci pour le code.

  5. #5
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Bon, Il y a plusieurs modifications à faire pour améliorer ton programme. Souhaites tu que je le modifie avant publication dans les sources ?

  6. #6
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Voici le code amélioré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    #!/usr/bin/perl 
    #~
    #~ Copyleft 2010 VelC.
    #~ This program is free software; you can redistribute it and/or
    #~ modify it under the same terms as Perl itself.
    #~
    #~ This program was originally written in french, therefore a lot of
    #~ variables have french names. Do not hesitate to change them if you
    #~ like.
    #~
    #~ For the CSS I choose to write it directly in each markup. That's
    #~ ugly and usually to ban but it was much more easier for me to do
    #~ so, since I don't know which cells have the same style, and so
    #~ which cells should have the same class.
    #~
    #~ This program was encoded in ISO-8859-1 (Western), so that it could
    #~ produce HTML files encoded in ISO-8859-1, as written in the header
    #~ I wrote. To change this, simply copy-paste the source code in a
    #~ UTF-8 file (for example) and change the HTML charset at line 199
    #~ (look for "charset" in the file and you'll find the relevant line).
    #~
    #~ See http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel-0.57/lib/Spreadsheet/ParseExcel.pm
    #~ for further details about the possibilities of SpreadSheet:ParseExcel
    #~
     
    use strict;
    use warnings;
    use Spreadsheet::ParseExcel qw (new Parse worksheets);
    use Getopt::Long;
    use Encode;
    use File::Basename;
    use XML::Writer;
    use IO::File;
     
    #~ The -s option define the normal font-size used in the page. For
    #~ example, -s 10 will define that the Excel font-size 10 equals 1em,
    #~ and thus that a font-size equals to 12 will be represented by 1.2em.
    #~ If left empty, the normal font-size will be 14.
     
    #~ The -n option define the sheets that must be treated. If left empty
    #~ or equals to zero, all sheets will be treated. If this value
    #~ contains greater numbers than the real number of sheets in the
    #~ Excel File, these numbers will be ignored. The first sheet is
    #~ the sheet 1 and not 0.
     
    #~ xls2html -n 1,2 file.xls file.html; # feuilles 1 et 2
    #~ xls2html -n 1..3,5 file.xls file.html; # feuilles 1 à 3 et 5
    #~ xls2html -n 2.. file.xls file.html; # toutes les feuilles à partir de la 2e
    #~ xls2html -n ..4 file.xls file.html; # les 4 premières feuilles
    #~ xls2html -n -1 file.xls file.html; # la dernière feuille
     
    #~ xls2html -n 1,2 file.xls file.html; # sheets 1 and 2
    #~ xls2html -n 1..3,5 file.xls file.html; # sheets 1 to 3 and 5
    #~ xls2html -n 2.. file.xls file.html; # every sheets from 2nd
    #~ xls2html -n ..4 file.xls file.html; # sheets 1 to 4
    #~ xls2html -n -1 file.xls file.html; # last sheet
     
    my ( $fileIn, $fileOut, $opt_s, $opt_n ) = ();
    GetOptions( 'in=s' => \$fileIn, 'out=s' => \$fileOut, 's=i' => \$opt_s, 'n=s' => \$opt_n );
    my $Usage = <<USAGE;
      Usage : $0 [-s number][-n number][-in File_in.xls][-out File_out.html]
    USAGE
     
    unless ( $fileIn =~ /\.xls$/ and $fileOut =~ /\.html?/ ) {
      die $Usage;
    }
     
    my $output;
     
    my $normal_size = 10;
    my @n_sheets;
    my $nb_sheets    = 0;
    my $parser       = Spreadsheet::ParseExcel->new();
    my $workbook     = $parser->parse($fileIn);
    my @worksheets   = $workbook->worksheets();
    my $sheets_count = $workbook->worksheet_count();
     
    if ( defined($opt_s) ) {
      ( $opt_s =~ /^(\d+\.?\d*|\.\d+)$/ && $opt_s > 0 && $opt_s < 100 )
        || die "The -s option has to be followed by a valid number !";
      $normal_size = $opt_s;
    }
     
    if ( defined($opt_n) ) {
      for ( my $i = 0; $i < $sheets_count; $i++ ) {
        $n_sheets[$i] = 0;
      }
     
      my @regtab;
      my $i = 0;
     
      while ( $opt_n =~ /(^\.\.\d+)|(\d+\.\.$)|(\d+\.\.\d+)|(\d+)|,/g ) {
        $regtab[ $i++ ] = $&;
      }
     
      if (@regtab) {
        for ( my $j = 0; $j < $i; $j++ ) {
          if ( $regtab[$j] =~ /^\.\.(\d+)$/ ) {
            for ( my $k = 0; $k < $1; $k++ ) {
              $n_sheets[$k] = 1;
            }
            $nb_sheets += $1;
          }
          elsif ( $regtab[$j] =~ /^(\d+)\.\.$/ ) {
            for ( my $k = $1 - 1; $k < $sheets_count; $k++ ) {
              $n_sheets[$k] = 1;
            }
            $nb_sheets += $sheets_count - $1 + 1;
          }
          elsif ( $regtab[$j] =~ /^(\d+)\.\.(\d+)$/ ) {
            for ( my $k = $1 - 1; $k < $2; $k++ ) {
              $n_sheets[$k] = 1;
            }
            $nb_sheets += $2 - $1 + 1;
          }
          elsif ( $regtab[$j] =~ /^(\d+)$/ ) {
            $n_sheets[ $1 - 1 ] = 1;
            $nb_sheets++;
          }
          elsif ( $regtab[$j] =~ /^,$/ ) {
     
            #~ does nothing, but ',' is a correct value
          }
          else {
            die "An error occured, incorrect option -n.";
          }
     
        }
      }
      else {
        die "The -n option has to be followed by a valid format ! Example : ..2,4,6..8,10..";
      }
    }
    else {
      for ( my $i = 0; $i < $sheets_count; $i++ ) {
        $n_sheets[$i] = 1;
        $nb_sheets++;
      }
    }
     
    my $filename;
    my $worksheet;
     
    for ( my $k = 0; $k < $sheets_count; $k++ ) {
      if ( $n_sheets[$k] ) {
        $worksheet = $workbook->worksheet($k);
        my $ligmax = $worksheet->row_range();
        my $colmax = $worksheet->col_range();
     
        if ( $fileIn =~ /^(.*)\.xls$/ && $nb_sheets == 1 ) {
          $filename = $1;
        }
        else {
          $filename = $worksheet->get_name();
        }
     
        #~ File where to write the result
        #~ If there's only one sheet to produce, the name of this sheet
        #~ isn't include in the name of the output file. Otherwise, it is
        #~ for each produced sheet.
        my ( $filename, $directories, $fileOutSuffix ) = fileparse( $fileOut, qr/\.[^.]*/ );
        if ( $nb_sheets == 1 ) {
          $output = new IO::File(">$directories/$filename$fileOutSuffix");
        }
        else {
          $output = new IO::File( ">$directories/$filename" . "-" . $fileOutSuffix );
        }
     
        my $writer = new XML::Writer(
          OUTPUT      => $output,
          DATA_INDENT => 3,         # indentation, 3 espace
          DATA_MODE   => 1,         # changement ligne.
          ENCODING    => 'utf-8',
        );
        $writer->doctype("html");
     
        #~ Beginning of the HTML file
        $writer->startTag(
          "html",
          "xmlns"    => "http://www.w3.org/1999/xhtml",
          "xml:lang" => "fr",
        );
        $writer->startTag("head");
        $writer->startTag("title");
        $writer->characters($filename);
        $writer->endTag("title");
        $writer->emptyTag(
          'meta',
          'http-equiv' => 'Content-Type',
          'content'    => 'text/html; charset=iso-8859-1'
        );
        $writer->endTag("head");
        $writer->startTag("body");
        $writer->startTag("table");
     
    #~ Iteration on each line and each column of the worksheet, writing down each cell from left to right and from top to bottom
     
        my $bloc  = '';
        my @cells = $worksheet->{Cells};
        for ( my $i = 0; $i <= $ligmax; $i++ ) {
          $writer->startTag("tr");
          for ( my $j = 0; $j <= $colmax; $j++ ) {
            my $cell = $cells[0][$i][$j];
            if ( defined($cell) ) {
              my $contenu  = $cell->value();
              my $format   = $cell->get_format();
              my $gras     = $format->{Font}->{Bold} ? "bold" : "normal";
              my $italique = $format->{Font}->{Italic} ? "italic" : "normal";
              my %font     = (
                "nom"      => $format->{Font}->{Name},
                "gras"     => $gras,
                "italique" => $italique,
                "taille"   => $format->{Font}->{Height},
                "couleur"  => $format->{Font}->{Color}
              );
     
              #~ 0 => No alignment
              #~ 1 => Left
              #~ 2 => Center
              #~ 3 => Right
              #~ 4 => Fill
              #~ 5 => Justify
              #~ 6 => Center across
              #~ 7 => Distributed/Equal spaced
              my $alignH
                = $format->{AlignH} == 3 ? "right"
                : ( $format->{AlignH} == 2 || $format->{AlignH} == 6 ) ? "center"
                : ( $format->{AlignH} == 5 || $format->{AlignH} == 4 ) ? "justify"
                :                                                        "left";
              my @fill    = $format->{Fill};
              my $couleur = $parser->ColorIdxToRGB( $fill[0][1] );
     
              $writer->startTag( "td",
                    "style" => "font-family:"
                  . $font{"nom"} . ';'
                  . 'font-size:'
                  . ( $font{"taille"} / $normal_size ) . 'em;'
                  . 'color:'
                  . $font{"couleur"} . ';'
                  . 'font-weight:'
                  . $font{"gras"} . ';'
                  . 'font-style:'
                  . $font{"italic"} . ';'
                  . 'text-align:'
                  . $alignH . ';'
                  . 'background:#'
                  . $couleur
                  . ';' );
              $writer->characters($contenu);
              $writer->endTag("td");
     
            }
          }
          $writer->endTag("tr");
        }
     
        $writer->endTag("table");
        $writer->endTag("body");
        $writer->endTag("html");
        $output->close();
      }
    }
    print "\nHTML successfully generated !\n";
    As toi de te baser dessus pour le compléter.

  7. #7
    Membre averti Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Par défaut
    Bonjour,

    Déjà bravo pour le script, c'est exactement ce que je cherchais à faire, tu me fais économiser pas mal d'heures de boulot

    J'ai une petite question :
    Si la feuille excel contient des liens hypertextes, quelle ligne faudrait-il ajouter/modifier pour que la page html les contienne également ?


    Merci d'avance.

  8. #8
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    L'analyse du paramètre -n gagnerait en lisibilité à utiliser des opérateurs sur tableau plutôt que des boucles for (i = 0 ; ... )

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      for ( my $i = 0; $i < $sheets_count; $i++ ) {
        $n_sheets[$i] = 0;
      }
    s'écrit aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @n_sheets = map 0, (1 .. $sheets_count);
    (pareil pour initialiser avec la valeur 1)

    Quant au traitement de la liste des feuilles, j'aurais plutôt vu une séparation en éléments à l'aide de splits plutôt qu'une recherche de pattern :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    use 5.10.0
    foreach my $sheets_range (split /,/, $opt_n) {
      my ($min, $max) = split /\.\./, $sheets_range;
     
      # This is a simple sheet number, max = min
      $max //= $min; # si perl 5.8 ecrire $max = defined $max ? $max : $min;
     
      # Check numeric values
      die("The -n option has to be followed by a valid format ! Example : ..2,4,6..8,10..") if grep !/^(-?\d+|)$/, ($min, $max);
     
      # No max defined, select all sheet up to the last one
      $max ||= $sheets_count;
      # No min defined, select all sheet from the first one
      $min ||= 1;
     
      my $i_min = $min > 0 ? $min - 1 : $sheets_count + $min;
      my $i_max = $max > 0 ? $max - 1 : $sheets_count + $max;
      $n_sheets[$_] = 1 foreach ($i_min) .. ($i_max);
    }
    J'ai testé grossièrement ce code, qui prend en compte des valeurs négatives, ce que le votre ne doit pas faire, sauf erreur.

    Une autre remarque : il serait judicieux de réaliser un suite de test (Test::Simple ou Test::More).

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 8
    Par défaut
    Citation Envoyé par djibril Voir le message
    Pour l'améliorer, faudrait utiliser XML::Writer. C'est plus propre pour la création de fichier balisé.
    Je vais y jeter un coup d'oeil, je ne connaissais pas.
    Citation Envoyé par djibril Voir le message
    Ensuite, après une première indentation du code, on obtient un programme plus compact et lisible :
    Cette remarque me surprend un peu puisque je mets un point d'honneur à indenter mon code, je trouve aussi cela illisible sans indentation
    Mais peut-être était-ce mon style d'indentation (mettre systématiquement l'accolade ouvrante à la ligne) qui te gênait ? C'est vrai que jusqu'à très récemment, je mettais toujours l'accolade ouvrante sur la même ligne que les "if", "for", etc. mais je trouve finalement plus clair de la mettre à la ligne. Chacun ses goûts
    Citation Envoyé par djibril Voir le message
    Bon, Il y a plusieurs modifications à faire pour améliorer ton programme. Souhaites tu que je le modifie avant publication dans les sources ?
    Je n'avais pas vu ta réponse, merci beaucoup, je regarde ça de suite. N'hésite pas à le modifier directement toi-même, en effet.
    Citation Envoyé par philouelgeek Voir le message
    Bonjour,

    Déjà bravo pour le script, c'est exactement ce que je cherchais à faire, tu me fais économiser pas mal d'heures de boulot

    J'ai une petite question :
    Si la feuille excel contient des liens hypertextes, quelle ligne faudrait-il ajouter/modifier pour que la page html les contienne également ?


    Merci d'avance.
    Je dois t'avouer que je n'ai pas étudié ce point, n'en ayant pas eu besoin pour mes fichiers Excel. Je ne crois pas avoir vu de méthodes dans la bibliothèque ParseExcel permettant de gérer les liens hypertextes, mais j'imagine qu'ils peuvent être récupérés directement dans le contenu de la cellule (dans mon code, c'est "$cell -> value()", sachant que "$cell -> unformatted()" permet aussi de récupérer le contenu mais non formaté). Si c'est le cas, il suffirait alors de parser ce contenu avec une petite expression régulière pour récupérer l'adresse pointée par le lien et de l'écrire dans une balise <a href="lien"></a>, comme d'habitude.
    Citation Envoyé par Philou67430 Voir le message
    L'analyse du paramètre -n gagnerait en lisibilité à utiliser des opérateurs sur tableau plutôt que des boucles for (i = 0 ; ... )

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      for ( my $i = 0; $i < $sheets_count; $i++ ) {
        $n_sheets[$i] = 0;
      }
    s'écrit aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @n_sheets = map 0, (1 .. $sheets_count);
    (pareil pour initialiser avec la valeur 1)

    Quant au traitement de la liste des feuilles, j'aurais plutôt vu une séparation en éléments à l'aide de splits plutôt qu'une recherche de pattern :

    J'ai testé grossièrement ce code, qui prend en compte des valeurs négatives, ce que le votre ne doit pas faire, sauf erreur.

    Une autre remarque : il serait judicieux de réaliser un suite de test (Test::Simple ou Test::More).
    Je dois vous avouer mon ignorance de ces possibilités : je ne suis pas un utilisateur expert en Perl, langage que je n'utilise qu'occasionnellement lorsque le besoin s'en fait ressentir. Du coup, je ne crois pas avoir déjà utilisé "split" ni "map" (ou alors, il y a fort longtemps) et je ne connais pas la bibliothèque Test (en fait je ne connais pas grand-chose en test ).

  10. #10
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    J'ai testé le code une seule fois, et pour le moment, il ne semble pas complétement fonctionner. Il y a encore plusieurs améliorations à apporter. Toutes les cellules ne sont pas encore récupérées. Je ne me suis pas encore penché sur les tas de regex qui pourraient être évitées comme l'a suggéré philou.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 8
    Par défaut
    Je suis assez surpris que toutes les cellules ne soient pas récupérées car je n'ai pas de problème de mon côté (peut-être n'ai-je pas testé avec des fichiers Excel un peu "exotiques", j'avoue n'avoir essayé qu'avec mes fichiers Excel qui ne contenaient que des tableaux mis en forme). Le problème vient peut-être de mon test de la valeur de $cell :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    for(my $i = 0 ; $i <= $ligmax ; $i++)
    		{
    			print FO "			<tr>\n";
    			for(my $j = 0 ; $j <= $colmax ; $j++)
    			{
    				my $cell = $cells[0][$i][$j];
    				if(defined($cell))
    				{
    Ce test permet d'éviter de recopier des cellules vides (un choix qui m'arrange et qui peut être facilement enlevé par l'utilisateur si besoin), il me semblait fonctionner chez moi.
    Ou alors, cela vient des valeurs de $colmax et $ligmax, mais toutes deux me sont données par la bibliothèque ParseExcel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $worksheet = $workbook -> worksheet($k);
    my $ligmax = $worksheet -> row_range();
    my $colmax = $worksheet -> col_range();
    Si ce n'est pas ça, alors je ne vois pas vraiment.

    Enfin, concernant les expressions régulières, en effet, elles sont beaucoup trop nombreuses pour l'option -n. Cela vient encore une fois de mon manque d'aisance avec Perl, j'ai tout simplement choisi cette solution car je n'arrivais pas à récupérer toutes les valeurs en une seule expression régulière.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 8
    Par défaut
    Citation Envoyé par djibril Voir le message
    J'ai testé le code une seule fois, et pour le moment, il ne semble pas complétement fonctionner. Il y a encore plusieurs améliorations à apporter. Toutes les cellules ne sont pas encore récupérées. Je ne me suis pas encore penché sur les tas de regex qui pourraient être évitées comme l'a suggéré philou.
    Je viens de tester le code corrigé que tu m'as envoyé au-dessus, et si c'est de celui-là dont tu parlais, effectivement il ne fonctionne pas parfaitement chez moi (notamment, il fusionne plusieurs feuilles et ne crée qu'un seul .html en sortie ne contenant pas le nom de la feuille courante). Je vais voir si je peux corriger cela, mais je ne suis pas sûr d'avoir beaucoup de temps à y consacrer d'ici ce soir.

    J'ai aussi identifié un problème un peu gênant de XML::Writer : il ne peut écrire que des fichiers en encodage utf-8 ou us-ascii, et ne peux pas écrire de iso-8859-1. Cela peut entraîner des problèmes sur certaines pages web, même en précisant le charset dans le header HTML

  13. #13
    Membre averti Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Par défaut
    Je dois t'avouer que je n'ai pas étudié ce point, n'en ayant pas eu besoin pour mes fichiers Excel. Je ne crois pas avoir vu de méthodes dans la bibliothèque ParseExcel permettant de gérer les liens hypertextes, mais j'imagine qu'ils peuvent être récupérés directement dans le contenu de la cellule (dans mon code, c'est "$cell -> value()", sachant que "$cell -> unformatted()" permet aussi de récupérer le contenu mais non formaté). Si c'est le cas, il suffirait alors de parser ce contenu avec une petite expression régulière pour récupérer l'adresse pointée par le lien et de l'écrire dans une balise <a href="lien"></a>, comme d'habitude.
    Si le lien hypertexte est affiché via un texte quelconque cela ne fonctionne pas.
    Par exemple j'ai un lien qui pointe vers "http://www.developpez.net/" mais dans la cellule excel il y a le texte "Site".

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 8
    Par défaut
    Je viens de jeter un coup d'œil, impossible de récupérer l'adresse du lien, que ce soit avec Cell::value() ou Cell::unformatted(). Je te suggère de chercher ton bonheur là-dedans :
    http://search.cpan.org/~jmcnamara/Sp...rseExcel-0.57/
    Mais je t'avoue que je suis un peu pessimiste, j'ai l'impression que ce cas de figure n'a pas été envisagé par les développeurs de la bibliothèque.

  15. #15
    Membre averti Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Par défaut
    Merci pour vos réponses, je vais regarder dans le lien que tu m'as donné.

Discussions similaires

  1. Ouvrir un fichier Excel à partir de code HTML
    Par jakline2010 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 9
    Dernier message: 02/08/2024, 20h12
  2. Conversion d'un fichier Excel au format XML
    Par DeadPooleuh dans le forum VB.NET
    Réponses: 2
    Dernier message: 17/02/2015, 13h43
  3. ouvrir fichier Excel dans page HTML : macro ne fonctionne pas
    Par bella1 dans le forum Général Conception Web
    Réponses: 0
    Dernier message: 30/06/2011, 09h50
  4. Conversion de documents word, excel, rtf, etc en HTML
    Par elitost dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 04/01/2008, 16h18
  5. Génération de fichiers Excel à partir de code HTML
    Par grincheux dans le forum ASP.NET
    Réponses: 2
    Dernier message: 01/06/2007, 14h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo