0

私のコードでは、CSV のすべてのデータを表形式で表示したいのですが、最後の行しか表示されません。1行目と2行目はどうですか?データは次のとおりです。

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

コードは次のとおりです。

#! /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>";
4

7 に答える 7

14

while ループでテーブル行を出力する必要があります。これは、行を読み取る場所であるためです。

コードを次のように変更します。

  • テーブル ヘッダーを出力します
  • ファイルを 1 行ずつ読み取り、テーブル行を出力します
  • 出力表フッター

少し単純化すると、ループは次のようになります...

while ($line=<F>)
{  
    print "<tr>";
    my @cells= split ',',$line;
    foreach my $cell (@cells)
    {
       print "<td>$cell</td>";
    }
    print "</tr>";
}
于 2008-10-14T06:30:25.963 に答える
7

HTML::Template はあなたの人生をずっと楽にしてくれるでしょう。これがカットダウンテンプレートの私の行き方です。

#!/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
于 2008-10-14T15:58:48.937 に答える
6
$f1,$f2,$f3,$f4

そのようなコードを目にするたびに、警報ベルが鳴るはずです。配列を使用します。

于 2008-10-15T01:39:48.513 に答える
5

より小さな例でデモンストレーションをさせてください。

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

上記のコードは、ファイル F のすべての行を読み取り、各行を変数 に割り当てます$f。新しい行が割り当てられるたびに、前の行が上書きされます。$fファイルの最後に到達すると、 onceの値が出力されます。

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

上記のコードはprintループ内にあるためprint、入力の各行に対して が実行されます。期待どおりの出力を得るには、コードに同様の変更を加える必要があります。

于 2008-10-14T06:28:50.787 に答える
3

最後の行しか表示されなかったのは、ファイル全体を読み取った後に印刷を実行し、次の行が読み取られたときに各行を破棄したためです。

正直なところ、そのコードにはさまざまな問題があります。いくつか言及し、以下のコード スニペットでそれらに対処します。

  1. 自分で CSV データを解析しないでください (分割)。Text::CSVまたは -- より良いパフォーマンスが必要な場合 -- Text::CSV_XSを使用します。
  2. HTML が無効です。すべてのタグを閉じる必要はありません。特に、タイトルは本文ではなく頭に入れる必要があります。
  3. 表形式のデータを Web ページに挿入するには、テンプレート モジュールを使用する必要があります。例: HTML::TemplateまたはTemplate Toolkit
  4. 少なくとも、関数を使用して冗長なコードを抽象化してください。
  5. さらに良いことに、データのフォーマットもデータであるという事実を利用してください。だからこそ、そのように扱われるべきです。
  6. 数字が付けられた変数 ( $f1$f2、...) をたくさん宣言していることに気付いた場合は、本当に配列が必要です。@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";
}
于 2008-10-14T15:54:51.800 に答える
0

<font>タグを閉じてください。ブラウザがそれらの不足を処理するからといって、それらを含める価値がないという意味ではありません。

于 2008-10-14T22:39:57.190 に答える