Question

Dans mon code, je souhaite afficher toutes les données d'un fichier CSV sous forme de tableau, mais la dernière ligne n'est affichée. Qu'en est-il des lignes 1 et 2? Voici les données:

1,HF6,08-Oct-08,34:22:13,df,jhj,fh,fh,ffgh,gh,g,rt,ffgsaf,asdf,dd,yoawa,DWP,tester,Pattern
2,hf35,08-Oct-08,34:12:13,dg,jh,fh,fgh,fgh,gh,gfh,re,fsaf,asdf,dd,yokogawa,DWP,DWP,Pattern
3,hf35,08-Oct-08,31:22:03,dg,jh,fh,fgh,gh,gh,gh,rte,ffgsaf,asdf,dfffd,yokogawa,DWP,DWP,ghh

Voici le code:

#! /usr/bin/perl
print "Content-type:text/html\r\n\r\n";
use CGI qw(:standard);
use strict;
use warnings;

my $line;
my $file;
my ($f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$f10,$f11,$f12,$f13,$f14,$f15,$f16,$f17,$f18,$f19);

$file='MyFile.txt';
open(F,$file)||die("Could not open $file");
while ($line=<F>)
{

($f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$f10,$f11,$f12,$f13,$f14,$f15,$f16,$f17,$f18,$f19)= split ',',$line;

}

close(F);

print "<HTML>";
print "<head>";
print "<body bgcolor='#4682B4'>";
print "<title>FUSION SHIFT REPORT</title>";
print "<div align='left'>";
print "<TABLE CELLPADDING='1' CELLSPACING='1' BORDER='1' bordercolor=black width='100%'>";
print "<TR>";
print "<td width='12%'bgcolor='#00ff00'><font size='2'>RECORD No.</td>";
print "<td width='12%'bgcolor='#00ff00'><font size='2'>TESTER No.</td>";
print "<td width='12%'bgcolor='#00ff00'><font size='2'>DATE</td>";
print "<td width='13%'bgcolor='#00ff00'><font size='2'>TIME</td>";
print "<td width='11%'bgcolor='#00ff00'><font size='2'>DEVICE NAME</td>";
print "<td bgcolor='#00ff00'><font size='2'>TEST PROGRAM</td>";
print "<td bgcolor='#00ff00'><font size='2'>DEVICE FAMILY</td>";
print "<td width='13%'bgcolor='#00ff00'><font size='2'>SMSLOT</td>";
print "<td width='13%'bgcolor='#00ff00'><font size='2'>DIE LOT</td>";
print "<td width='12%'bgcolor='#00ff00'><font size='2'>LOADBOARD</td>";
print "<td width='12%'bgcolor='#00ff00'><font size='2'>TESTER </td>";
print "<td width='12%'bgcolor='#00ff00'><font size='2'>SERIAL NUMBER</td>";
print "<td width='13%'bgcolor='#00ff00'><font size='2'>TESTER CONFIG</td>";
print "<td width='11%'bgcolor='#00ff00'><font size='2'>SMSLOT</td>";
print "<td bgcolor='#00ff00'><font size='2'>PACKAGE</td>";
print "<td bgcolor='#00ff00'><font size='2'>SOCKET</td>";
print "<td width='13%'bgcolor='#00ff00'><font size='2'>ROOT CAUSE 1</td>";
print "<td width='13%'bgcolor='#00ff00'><font size='2'>ROOT CAUSE 2</td>";
print "<td width='13%'bgcolor='#00ff00'><font size='2'>ROOT CAUSE 3</td>";
print "</tr>";
print "<TR>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f1</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f2</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f3</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f4</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f5</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f6</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f7</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f8</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f9</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f10</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f11</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f12</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f13</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f14</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f15</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f16</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f17</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f18</TD>";
print "<TD bgcolor='#ADD8E6'><font size='2'>$f19</TD>";
print "</tr>";

print "</TABLE>";

print "</body>";
print "<html>";
Était-ce utile?

La solution

HTML :: Template vous faciliterait grandement la vie. Voici mon go avec un modèle réduit.

#!/usr/local/bin/perl

use strict;
use warnings;

use HTML::Template;

my @table;
while (my $line = <DATA>){
    chomp $line;
    my @row = map{{cell => $_}} split(/,/, $line);
    push @table, {row => \@row};
}

my $tmpl = HTML::Template->new(scalarref => \get_tmpl());
$tmpl->param(table => \@table);
print $tmpl->output;

sub get_tmpl{
    return <<TMPL
<html>
<TMPL_LOOP table>
<tr>
<TMPL_LOOP row>
<td><TMPL_VAR cell></td></TMPL_LOOP>
</tr></TMPL_LOOP>
</html>
TMPL
}

__DATA__
1,HF6,08-Oct-08,34:22:13,df,jhj,fh,fh,ffgh,gh,g,rt,ffgsaf,asdf,dd,yoawa,DWP,tester,Pattern
2,hf35,08-Oct-08,34:12:13,dg,jh,fh,fgh,fgh,gh,gfh,re,fsaf,asdf,dd,yokogawa,DWP,DWP,Pattern
3,hf35,08-Oct-08,31:22:03,dg,jh,fh,fgh,gh,gh,gh,rte,ffgsaf,asdf,dfffd,yokogawa,DWP,DWP,ghh

Autres conseils

Vous devez générer les lignes de la table à l'intérieur de la boucle while, car c'est là que vous lisez les lignes.

Alors changez le code pour qu'il

  • affiche les en-têtes de tableau
  • lit le fichier ligne par ligne affichant les lignes du tableau
  • sortie du pied de table

Voici à quoi pourrait ressembler votre boucle si elle était un peu simplifiée ...

while ($line=<F>)
{  
    print "<tr>";
    my @cells= split ',',$line;
    foreach my $cell (@cells)
    {
       print "<td>$cell</td>";
    }
    print "</tr>";
}
$f1,$f2,$f3,$f4

Chaque fois que vous voyez un code comme celui-ci, les sonneries doivent sonner Utilisez un tableau.

Permettez-moi de vous présenter un exemple plus petit.

my $f;
while ($line = <F>) {
    $f = $line;
}
print $f;

Le code ci-dessus lira toutes les lignes du fichier F, en assignant chaque ligne à la variable $f. Chaque fois qu'il assigne une nouvelle ligne, la ligne précédente est écrasée. Lorsqu'il atteint la fin du fichier, il affiche la valeur print une fois.

my $f;
while ($line = <F>) {
    $f = $line;
    print $f;
}

Le code ci-dessus contient le <=> dans la boucle. Le <=> sera exécuté pour chaque ligne de l'entrée. Vous voudrez apporter une modification similaire à votre code pour obtenir le résultat attendu.

La raison pour laquelle vous ne voyiez que la dernière ligne est que vous avez exécuté l'impression après avoir lu l'intégralité du fichier et supprimé toutes les lignes lors de la lecture de la suivante.

Pour être honnête, il y a plusieurs problèmes avec ce code. Je mentionnerai quelques-uns et traiterai ceux-ci dans le code ci-dessous.

  1. Ne pas analyser les données CSV vous-même (la scission). Utilisez Text :: CSV ou - si vous avez besoin de meilleures performances - Text :: CSV_XS .
  2. Votre code HTML n'est pas valide. Vous ne fermez pas toutes les balises et en particulier, le titre doit être en tête, mais pas dans le corps.
  3. Vous devriez utiliser un module de gabarit pour insérer des données tabulaires dans une page Web. Exemples: HTML :: Modèle ou Boîte à outils pour modèles .
  4. À tout le moins, utilisez des fonctions pour extraire le code redondant.
  5. Mieux encore, utilisez le fait que le formatage des données est également des données. C’est pourquoi il devrait être traité comme tel.
  6. Si vous constatez que vous déclarez un grand nombre de variables avec des nombres ($f1, $f2, ...), vous voulez vraiment un tableau: @fields = split /,/, $line;
use strict;
use warnings;
use CGI qw();
use Text::CSV;

my $cgi = CGI->new();
print $cgi->header();

my $file ='MyFile.txt';

# should really use a templating module from CPAN,
# but let's take it step by step.
# Any of the following would fit nicely:
# - Template.pm (Template Toolkit)
# - HTML::Template, etc.
my $startHtml = <<'HERE';
<html>
<head> <title>FUSION SHIFT REPORT</title> </head>
<body bgcolor="#4682B4">
<div align="left">
<table cellpadding="1" cellspacing="1" border="1" bordercolor="black" width="100%">
HERE
my $endHtml = <<'HERE';

</table>

</body>
<html>
HERE

my @columns = (
  { name => 'RECORD No.', width => 12 },
  { name => 'TESTER No.', width => 12 },
  { name => 'DATE', width => 12 },
  { name => 'TIME', width => 13 },
  { name => 'DEVICE NAME', width => 11 },
  { name => 'TEST PROGRAM' },
  { name => 'DEVICE FAMILY' },
  { name => 'SMSLOT', width => 13 },
  { name => 'DIE LOT', width => 13 },
  { name => 'LOADBOARD', width => 12 },
  { name => 'TESTER', width => 12 },
  { name => 'SERIAL NUMBER', width => 12 },
  { name => 'TESTER CONFIG', width => 13 },
  { name => 'SMSLOT', width => 11 },
  { name => 'PACKAGE' },
  { name => 'SOCKET' },
  { name => 'ROOT CAUSE 1', width => 13 },
  { name => 'ROOT CAUSE 2', width => 13 },
  { name => 'ROOT CAUSE 3', width => 13 },
);


my $csv = Text::CSV->new();
open my $fh, '<', $file
  or die "Could not open file '$file': $!"; # should generate a HTML error here

# print header
print $startHtml;
print_table_header(\@columns);

while (defined(my $line = <$fh>)) {
  $csv->parse($line);
  # watch out: This may be "tainted" data!
  my @fields = $csv->fields();
  @fields = @fields[0..$#columns] if @fields > @columns;
  print_table_line(\@fields);
}

close $fh;

print $endHtml;




sub print_table_header {
  my $columns = shift;
  print "<tr>\n";
  foreach my $column (@$columns) {
    my $widthStr = (defined($column->{width}) ? ' width="'.$column->{width}.'"' : '');
    my $colName = $column->{name};
    print qq{<td$widthStr bgcolor="#00FF00"><font size="2">$colName</font></td>\n};
  }
  print "</tr>\n";
}

sub print_table_line {
  my $fields = shift;
  print "<tr>\n";
  foreach my $field (@$fields) {
    print qq{<td bgcolor=\"#ADD8E6\"><font size="2">$field</font></td>\n};
  }
  print "</tr>\n";
}

Fermez votre & police > Mots clés. Ce n’est pas parce que le navigateur gérera leur manque que cela ne vaut pas la peine de les inclure.

Ce n’est pas la solution la plus robuste, c’est en fait quelques échecs assez graves si vous avez des virgules dans les valeurs, mais cela a fonctionné à ma place:

(les données CSV sont dans une variable appelée $ content)

$content =~ s#\n#</td></tr><tr><td>#g;
$content =~ s#,#</td><td>#g;
$content = "<table><tr><td>$content</td></tr></table>";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top