Create an HTML table

From Rosetta Code
Revision as of 08:21, 28 September 2011 by rosettacode>Georg Peter (Add Seed7 example)
Task
Create an HTML table
You are encouraged to solve this task according to the task description, using any language you may know.

Create an HTML table.

  • The table body should have at least three rows of three columns.
  • Each of these three columns should be labelled "X", "Y", and "Z".
  • An extra column should be added at either the extreme left or the extreme right of the table that has no heading, but is filled with sequential row numbers.
  • The rows of the "X", "Y", and "Z" columns should be filled with random or sequential integers having 4 digits or less.
  • The numbers should be aligned in the same fashion for all columns.

Ada

<lang Ada>with Ada.Text_IO; with Ada.Numerics.Discrete_Random;

procedure HTML_Table is

   use Ada.Text_IO;
   function Blanks(N: Natural) return String is
   begin
      if N=0 then
         return "";
      else
         return " " & Blanks(N-1);
      end if;
   end Blanks;
   package Table is
      type Four_Digits is mod 10_000;
      package Rand is new Ada.Numerics.Discrete_Random(Four_Digits);
      Gen: Rand.Generator;
      type object is tagged null record;
      procedure Print(T: Object; Rows: Natural);
      procedure Print_Header(T: Object);
      procedure Print_Body(T: Object; Rows: Natural);
      procedure Print_Row(T: Object; Row_Number: Positive);
   end Table;
   package body Table is
      procedure Print_Row(T: Object; Row_Number: Positive) is
      begin

Put(Blanks(4) & "" & Positive'Image(Row_Number) & "");

         for I in 1 .. 3 loop

Put("" & Four_Digits'Image(Rand.Random(Gen)) & "");

         end loop;

Put_Line(""); end Print_Row; procedure Print_Body(T: Object; Rows: Natural) is begin Put_Line(Blanks(2)&"<tbody align = ""right"">"); for I in 1 .. Rows loop T.Print_Row(I); end loop; Put_Line(Blanks(2)&"</tbody>"); end Print_Body; procedure Print_Header(T: Object) is begin Put_Line(Blanks(2) & "<thead align = ""right"">"); Put_Line(Blanks(4) & "XY" & "Z");

         Put_Line(Blanks(2) & "</thead>");
      end Print_Header;
      procedure Print(T: Object; Rows: Natural) is
      begin

Put_Line("

"); T.Print_Header; T.Print_Body(Rows); Put_Line("

");

      end Print;
   begin
      Rand.Reset(Gen);
   end Table;
   T: Table.Object;

begin

  T.Print(Rows => 4);

end HTML_Table;</lang>

Each time you run the program, you get different random values for the table. Here is a sample output:

<lang html5>

<thead align = "right">
 </thead>
 <tbody align = "right">
 </tbody>
XYZ
1 5091 395 6319
2 7099 746 173
3 1701 3897 2124
4 8539 1696 1417

</lang>

Viewing the output with Lynx:

        X    Y    Z
   1 5091  395 6319
   2 7099  746  173
   3 1701 3897 2124
   4 8539 1696 1417

AutoHotkey

Translation of: C

<lang AutoHotkey>out =

Loop 4

out .= "`r`n" out .= "`r`n
XYZ
" A_Index "" Rand() "" Rand() "" Rand() "

"

MsgBox % clipboard := out

Rand(u=1000){

   Random, n, 1, % u
   return n

}</lang> Output:

XYZ
128955643
2102100971
3582295264
4396762633

C

<lang C>#include <stdio.h>

  1. include <stdlib.h>

int main() { int i;

printf("

" "");

for (i = 0; i < 4; i++) {

printf("", i,

rand() % 10000, rand() % 10000, rand() % 10000); }

printf("
XYZ
%d%d%d%d

");

return 0;

}</lang>output (wiki doesn't like tbody/thead tags):

XYZ
027778869383
1833577936915
266494925386
32723621421

C++

<lang cpp>#include <fstream>

  1. include <boost/array.hpp>
  2. include <string>
  3. include <cstdlib>
  4. include <ctime>
  5. include <sstream>

void makeGap( int gap , std::string & text ) {

  for ( int i = 0 ; i < gap ; i++ ) 
     text.append( " " ) ;

}

int main( ) {

  boost::array<char , 3> chars = { 'X' , 'Y' , 'Z' } ;
  int headgap = 3 ;
  int bodygap = 3 ;
  int tablegap = 6 ;
  int rowgap = 9 ;
  std::string tabletext( "<html>\n" ) ;
  makeGap( headgap , tabletext ) ;
  tabletext += "<head></head>\n" ;
  makeGap( bodygap , tabletext ) ;
  tabletext += "<body>\n" ;
  makeGap( tablegap , tabletext ) ;

tabletext += "

\n" ; makeGap( tablegap + 1 , tabletext ) ; tabletext += "<thead align=\"right\">\n" ; makeGap( tablegap, tabletext ) ; tabletext += "" ;
  for ( int i = 0 ; i < 3 ; i++ ) {
tabletext += "" ; } tabletext += "\n" ; makeGap( tablegap + 1 , tabletext ) ; tabletext += "</thead>" ; makeGap( tablegap + 1 , tabletext ) ; tabletext += "<tbody align=\"right\">\n" ; srand( time( 0 ) ) ; for ( int row = 0 ; row < 5 ; row++ ) { makeGap( rowgap , tabletext ) ; std::ostringstream oss ; tabletext += "" ; } tabletext += "\n" ; } makeGap( tablegap + 1 , tabletext ) ; tabletext += "</tbody>\n" ; makeGap( tablegap , tabletext ) ; tabletext += "
" ;
     tabletext += *(chars.begin( ) + i ) ;
tabletext += "
" ;
     oss << row ;
     tabletext += oss.str( ) ;
     for ( int col = 0 ; col < 3 ; col++ ) {

oss.str( "" ) ; int randnumber = rand( ) % 10000 ; oss << randnumber ;

tabletext += "
" ;

tabletext.append( oss.str( ) ) ;

tabletext += "

\n" ;

  makeGap( bodygap , tabletext ) ;
  tabletext += "</body>\n" ;
  tabletext += "</html>\n" ;
  std::ofstream htmltable( "testtable.html" , std::ios::out | std::ios::trunc ) ;
  htmltable << tabletext ;
  htmltable.close( ) ;
  return 0 ;

}</lang> Output ( of testtable.html ): <LANG html5><html>

  <head></head>
  <body>
<thead align="right">
      </thead>
      <tbody align="right">
      </tbody>
XYZ
012746847352
184665774612
2754316448143
3492857148186
4343674939344
  </body>

</html> </LANG>

Delphi

<lang Delphi>program CreateHTMLTable;

{$APPTYPE CONSOLE}

uses SysUtils;

function AddTableRow(aRowNo: Integer): string; begin

Result := Format(' %d%d%d%d',

   [aRowNo, Random(10000), Random(10000), Random(10000)]);

end;

var

 i: Integer;

begin

 Randomize;

Writeln('

'); Writeln(' ');
 for i := 1 to 4 do
   Writeln(AddTableRow(i));
Writeln('
XYZ

');

 Readln;

end.</lang>

Output:

<lang html5>

XYZ
1737126591393
2671050255203
3131615992086
4478566125042

</lang>

Euphoria

<lang euphoria>puts(1,"

\n") puts(1," \n")

for i = 1 to 3 do

printf(1," ",i)
   for j = 1 to 3 do
printf(1,"",rand(10000))
   end for
puts(1,"\n") end for puts(1,"
XYZ
%d%d

")</lang>

Sample output:

<lang html5>

XYZ
1797873762382
2363219478900
3409815632762

</lang>

Go

Template is a package in the standard library. <lang go>package main

import (

   "fmt"
   "os"
   "template"

)

type Row struct {

   X, Y, Z int

}

var tmpl = `

Template:Range $ix, $row := .Template:End
XYZ
Template:$ixTemplate:$row.XTemplate:$row.YTemplate:$row.Z

`

func main() {

   // create template
   ct := template.Must(new(template.Template).Parse(tmpl))
   // make up data
   data := make([]Row, 4)
   for r := range data {
       data[r] = Row{r*3, r*3+1, r*3+2}
   }
   // open output file
   hf, err := os.Create("table.html")
   if err != nil {
       fmt.Println(err)
       return
   }
   defer hf.Close()
   // apply template to data
   if err := ct.Execute(hf, data); err != nil {
       fmt.Println(err)
   }

}</lang> Output in table.html: <lang html5>

XYZ
0012
1345
2678
391011

</lang>

Icon and Unicon

<lang Icon>procedure main()

printf("

\n ")

every r := 1 to 4 do {

printf("\n ",r) every 1 to 3 do printf("",?9999) # random 4 digit numbers per cell
  }
printf("\n
XYZ
%d%d

\n")

end

link printf </lang>

printf.icn provides printf

Sample Output:<lang html5>

XYZ
1312932947013
250451695761
370019634183
4169511581240

</lang>

J

We can define:

<lang j>ele=:4 :0

 nm=. x-.LF
 lf=. x-.nm
 ;('<',nm,'>') ,L:0 y ,L:0 '</',nm,'>',lf

)

hTbl=:4 :0

 rows=. 'td' <@ele"1 ":&.>y
 'table' ele ('tr',LF) <@ele ('th' ele x); rows

)</lang>

With these definitions:

<lang j> (;;:'X Y Z') hTbl ":&.>(i.5),.i.5 3

XYZ
0012
1345
2678
391011
4121314

</lang>

Or, if running under jhs:

<lang j>jhtml (;;:'X Y Z') hTbl ":&.>(i.5),.i.5 3</lang>

to display the table inline, as html.

Java

Works with: Java version 1.5+

This example assumes the header row is the first row in the given array and does not add row numbers. They will need to be added by the programmer when constructing the array. <lang java5>public class HTML {

public static String array2HTML(Object[][] array){ StringBuilder html = new StringBuilder(

"

"); for(Object elem:array[0]){ html.append("");

} for(int i = 1; i < array.length; i++){ Object[] row = array[i];

html.append(""); for(Object elem:row){ html.append("");

}

html.append(""); } html.append("
" + elem.toString() + "
" + elem.toString() + "

");

return html.toString(); }

public static void main(String[] args){ Object[][] ints = {{"","X","Y","Z"},{1,1,2,3},{2,4,5,6},{3,7,8,9},{4,10,11,12}}; System.out.println(array2HTML(ints)); } }</lang> Output:

<lang html5>

XYZ
1123
2456
3789
4101112

</lang>

JavaScript

<lang html><html><head>

 <title>Show a table with row and column headings</title>
 <style type="text/css">
   th:first-child, td { padding: 0 .5em; text-align: right; }
 </style>
 <script>
 function fill(table) {
   for (var i = 1; i <= 100; i++) {
     var row = document.createElement("tr");
     var hcell = document.createElement("th");
     hcell.appendChild(document.createTextNode(""+i));
     row.appendChild(hcell);
     for (var j = 0; j < 3; j++) {
       var cell = document.createElement("td");
       cell.appendChild(document.createTextNode(""+Math.floor(Math.random()*10000)));
       row.appendChild(cell);
     }
     table.appendChild(row);
   }
 }
 </script>

</head><body>

XYZ

<script>fill(document.getElementById("x"));</script> </body></html></lang>

Liberty BASIC

This creates and saves an html file, then calls web browser to display it.
A time delay is needed to allow this, then the file is deleted. <lang lb>

   nomainwin
   quote$ =chr$( 34)
   html$  ="<html><head></head><body>"

html$ =html$ +"

"
   for i =1 to 4
       d1$ =str$( i)
       d2$ =str$( int( 10000 *rnd( 1)))
       d3$ =str$( int( 10000 *rnd( 1)))
       d4$ =str$( int( 10000 *rnd( 1)))
html$ =html$ +""
   next i
html$ =html$ +"
X Y Z
"; d1$; " " +d2$ +" " +d3$ +" " +d4$ +"

"

   html$ =html$ +"</body></html>"
   open "table.html" for output as #o
       #o html$;
   close #o
   address$ ="table.html"
   run "explorer.exe "; address$
   timer 5000, [on]
   wait
   [on]
   timer 0
   kill "table.html"
   wait

sub quit w$

   close #w$
   end

end sub </lang>


Modula-2

<lang modula2>MODULE testCGI;

FROM InOut IMPORT WriteCard, WriteLn, WriteString, WriteBf; FROM Arguments IMPORT ArgTable, GetEnv; FROM Strings IMPORT Assign, Length, String;

VAR EnvVars  : ArgTable;

PROCEDURE ReadEnvVar;

VAR Value  : String;

     i              : CARDINAL;

BEGIN

WriteString ('

'); WriteString ('');
  i := 0;
  LOOP
     IF  EnvVars^ [i] = NIL  THEN  EXIT  END;
     Assign (Value, EnvVars^ [i]^);
WriteString ('"); WriteLn; INC (i) END; WriteString("
IndexLengthContent
');
     WriteCard (i, 2);
WriteString ('
');
     WriteCard (Length (Value), 3);
WriteString ('
'); WriteString (Value); WriteString ("

");

END ReadEnvVar;

BEGIN

  GetEnv (EnvVars);
  WriteString ('Content-type:text/html');
  WriteLn;
  WriteLn;
  WriteString ('<html><head>');
  WriteString ('<title>CGI with the Mocka Modula-2 compiler</title>');
  WriteString ('</head><body>');
  WriteLn;

WriteString ('

CGI environment passed along by your browser

');

  ReadEnvVar;
  WriteString ('</body></html>');
  WriteLn;
  WriteBf

END testCGI.</lang>

Oz

As a complete web application, using the "Roads" web programming library. Connect your browser to http://localhost:8080/table after starting the program. <lang oz>declare

[Roads] = {Module.link ['x-ozlib://wmeyer/roads/Roads.ozf']}

fun {Table Session}

  html(
     head(title("Show a table with row and column headings")

style(type:"text/css" css(td 'text-align':center) ))

     body(

{TagFromList table tr(th th("X") th("Y") th("Z")) | {CreateRows 3 5} })) end

fun {CreateRows NumCols NumRows}

  {List.map {List.number 1 NumRows 1}
   fun {$ Row}
      {TagFromList tr

td( {Int.toString Row} ) | {List.map {List.number 1 NumCols 1} fun {$ Col} SequentialNumber = (Row-1)*NumCols + Col in td( {Int.toString SequentialNumber} ) end }}

   end
  }

end

TagFromList = List.toTuple

in

{Roads.registerFunction table Table} {Roads.run}</lang>

Perl

<lang Perl>my @heading = qw(X Y Z); my $rows = 5;

print '

<thead>" } @heading),
       "</thead><tbody>";

for (1 .. $rows) {

print "", (map { "" } @heading), ""; } print "</tbody>
', (map { "$_
$_".int(rand(10000))."

";</lang>

Note that this is a rather inane way (because of the inane task specification) of generating structured document. For serious work, one should use a module such as XML or HTML for well-formedness instead of this ad hoc method.

Perl 6

This is certainly not the only or best way to generate HTML tables using Perl 6; just an example of one possible method.

<lang Perl6>my @header = <  X Y Z>; my $rows = 5;

sub tag ($tag, $string, $param?) { return "<$tag" ~ ($param ?? " $param" !! ) ~ ">$string" ~ "</$tag>" };

my $table = tag('tr', ( tag('th', $_) for @header));

for 1 .. $rows -> $row {

   $table ~=  tag('tr', ( tag('td', $row, 'align="right"')
   ~ (tag('td', (^10000).pick, 'align="right"') for 1..^@header)));  

}

say tag('table', $table, 'cellspacing=4 style="text-align:right; border: 1px solid;"');</lang>

Sample output:

  X Y Z
12179 4778 2717
22160 1592 4348
34511 540 7187
43484 5882 1273
51310 4017 410

PicoLisp

<lang PicoLisp>(load "@lib/xhtml.l")

(

NIL NIL '(NIL (NIL "X") (NIL "Y") (NIL "Z")) (for N 3 (<row> NIL N 124 456 789) ) )</lang>

PL/I

<lang PL/I> /* Create an HTML table. 6/2011 */

create: procedure options (main);


create_table: procedure (headings, table_contents);

  declare headings(*) character (10) varying;
  declare table_contents(*, *) fixed;
  declare (i, row, col) fixed;
put skip edit ('
') (a); /* Headings. */ put skip edit (' ') (a);
                              /* For an empty column heading */
  do i = 1 to hbound(headings);
put edit (' ' ) (a);
  end;
put edit ('') (a); /* Table contents. */ do row = 1 to hbound(table_contents, 1); /* row number */ put skip edit (' ') (a);
     /* row contents */
     do col = 1 to hbound(table_contents, 2);
put edit (' ' ) (a);
     end;
put edit ('') (a); end; put skip edit ('
', headings(i), '
', row, '', table_contents(row, col), '

' ) (a);

end create_table;

  declare headings (3) character (1) static initial ('X', 'Y', 'Z');
  declare table_contents(3, 3) fixed static initial (
     4, -3, 8,
     7, 2, -6,
     11, 1, 15);
  call create_table (headings, table_contents);

end create;

Protium

Opcodes of interest: SDC -- simple document; R!I -- ranged random integer

<lang html><@ SDCLIT> <@ DTBLIT> <@ DTRLITLIT> <@ DTDLITLIT>|[style]background-color:white</@> <@ DTD>X</@> <@ DTD>Y</@> <@ DTD>Z</@>|[style]width:100%; background-color:brown;color:white; text-align:center</@> <@ ITEFORLIT>10| <@ DTRLITCAP> <@ DTDPOSFORLIT>...|[style]background-color:Brown; color:white; text-align:right</@> <@ DTDCAPLIT><@ SAYR!ILI2>1|9999</@>|[style]width:50;text-align:right</@> <@ DTDCAPLIT><@ SAYR!ILI2>1|9999</@>|[style]width:50;text-align:right</@> <@ DTDCAPLIT><@ SAYR!ILI2>1|9999</@>|[style]width:50;text-align:right</@> |[style]background-color:white;color:black</@> </@> </@> |Number Table</@></lang>

Python

<lang python> import random

def rand9999():

   return random.randint(1000, 9999)

def tag(attr=, **kwargs):

   for tag, txt in kwargs.items():
       return '<{tag}{attr}>{txt}</{tag}>'.format(**locals())

if __name__ == '__main__':

   header = tag(tr=.join(tag(th=txt) for txt in ',X,Y,Z'.split(','))) + '\n'
   rows = '\n'.join(tag(tr=.join(tag(' style="font-weight: bold;"', td=i)
                                   + .join(tag(td=rand9999())
                                             for j in range(3))))
                    for i in range(1, 6))
   table = tag(table='\n' + header + rows + '\n')
   print(table)</lang>

Sample output

XYZ
1604046977055
2252554686901
3885137278379
4531343961765
5401359246082

The raw HTML

<lang html5>

XYZ
1604046977055
2252554686901
3885137278379
4531343961765
5401359246082

</lang>

Retro

Using the casket::html' library which allows creation of HTML using quotes and combinators:

<lang Retro>needs casket::html' with casket::html'

rnd ( -$ ) random 1000 mod toString ;

[ [ [ ] td [ "x" ] td [ "y" ] td [ "z" ] td ] tr

 [ [ "1" ] td [ rnd ] td [ rnd ] td [ rnd ] td ] tr
 [ [ "2" ] td [ rnd ] td [ rnd ] td [ rnd ] td ] tr
 [ [ "3" ] td [ rnd ] td [ rnd ] td [ rnd ] td ] tr
 [ [ "4" ] td [ rnd ] td [ rnd ] td [ rnd ] td ] tr
 [ [ "5" ] td [ rnd ] td [ rnd ] td [ rnd ] td ] tr
 [ [ "6" ] td [ rnd ] td [ rnd ] td [ rnd ] td ] tr

] table</lang>

Ruby

This creates a plain HTML table, without any CSS to draw borders or to set column widths.

Library: REXML

<lang ruby>def r; rand(10000); end table = [["", "X", "Y", "Z"],

        [ 1,   r,   r,   r],
        [ 2,   r,   r,   r],
        [ 3,   r,   r,   r]]

require 'rexml/document'

xtable = REXML::Element.new("table") table.each do |row|

 xrow = REXML::Element.new("tr", xtable)
 row.each do |cell|
   xcell = REXML::Element.new("td", xrow)
   REXML::Text.new(cell.to_s, false, xcell)
 end

end

formatter = REXML::Formatters::Pretty.new formatter.compact = true formatter.write(xtable, $stdout)</lang>

Output: <lang html5>

X Y Z
1 1358 6488 6434
2 2477 6493 1330
3 240 3038 9849

</lang>

Scheme

Works with: Guile
Works with: Gauche

<lang scheme>(define table #(

               #("" "X" "Y" "Z")
               #(1 1 2 3)
               #(2 4 5 6)
               #(3 7 8 9)))

(display "

") (do ((r 0 (+ r 1))) ((eq? r (vector-length table))) (display "") (do ((c 0 (+ c 1))) ((eq? c (vector-length (vector-ref table r)))) (if (eq? r 0) (display ""))) (display "")) (display "
"))
               (if (> r 0)
(display "
"))
               (display (vector-ref (vector-ref table r) c))
               (if (eq? r 0)
(display "")) (if (> r 0) (display "

")</lang>

Seed7

<lang seed7>$ include "seed7_05.s7i";

const proc: main is func

 local
   var integer: line is 0;
   var integer: column is 0;
 begin

writeln("

"); writeln("");
   for line range 1 to 3 do
write("");
     for column range 1 to 3 do
write("");
     end for;
writeln(""); end for; writeln("
XYZ
" <& line <& "" <& rand(0, 9999) <& "

")

 end func;</lang>

Output:

<table style="text-align:center; border: 1px solid">
<tr><th></th><th>X</th><th>Y</th><th>Z</th></tr>
<tr><th>1</th><td>9682</td><td>2439</td><td>7698</td></tr>
<tr><th>2</th><td>2958</td><td>4336</td><td>8340</td></tr>
<tr><th>3</th><td>6245</td><td>6544</td><td>457</td></tr>
</table>

Output viewed with a browser:

XYZ
1968224397698
2295843368340
362456544457

Tcl

<lang tcl># Make ourselves a very simple templating lib; just two commands proc TAG {name args} {

   set body [lindex $args end]
   set result "<$name"
   foreach {t v} [lrange $args 0 end-1] {

append result " $t=\"" $v "\""

   }
   append result ">" [string trim [uplevel 1 [list subst $body]]] "</$name>"

} proc FOREACH {var lst str} {

   upvar 1 $var v
   set result {}
   set s [list subst $str]
   foreach v $lst {append result [string trim [uplevel 1 $s]]}
   return $result

}

  1. Build the data we're displaying

set titles {"" "X" "Y" "Z"} set data {} for {set x 0} {$x < 4} {incr x} {

   # Inspired by the Go solution, but with extra arbitrary digits to show 4-char wide values
   lappend data [list \

[expr {$x+1}] [expr {$x*3010}] [expr {$x*3+1298}] [expr {$x*2579+2182}]] }

  1. Write the table to standard out

puts [TAG table border 1 {

   [TAG tr bgcolor #f0f0f0 {

[FOREACH head $titles { [TAG th {$head}] }]

   }]
   [FOREACH row $data {

[TAG tr bgcolor #ffffff { [FOREACH col $row { [TAG td align right {$col}] }] }]

   }]

}]</lang>

TUSCRIPT

<lang tuscript> $$ MODE TUSCRIPT tablefile="table.html" ERROR/STOP CREATE (tablefile,FDF-o,-std-) ACCESS d: WRITE/ERASE/RECORDS/utf8 $tablefile s,tablecontent tablecontent=* WRITE d "<!DOCTYPE html system>" WRITE d "<html><head><title>create html table</title></head>"

WRITE d "<body>

<thead align='right'>" WRITE d ""

WRITE d "</thead>" WRITE d "<tbody align='right'>" LOOP n=1,5 x=RANDOM_NUMBERS (1,9999,1) y=RANDOM_NUMBERS (1,9999,1) z=RANDOM_NUMBERS (1,9999,1)

WRITE d ""

ENDLOOP

WRITE d "</tbody>
 xyz
{n}{x}{y}{z}

</body></html>"

ENDACCESS d BROWSE $tablefile </lang> Output:

<!DOCTYPE html system>
<html><head><title>create html table</title></head>
<body><table><thead align='right'>
<tr><th> </th><th>x</th><th>y</th><th>z</th></tr>
</thead>
<tbody align='right'>
<tr><td>1</td><td>268</td><td>2409</td><td>8627</td></tr>
<tr><td>2</td><td>2095</td><td>1455</td><td>269</td></tr>

<tr><td>3</td><td>3763</td><td>9225</td><td>1957</td></tr>
<tr><td>4</td><td>1304</td><td>9434</td><td>2208</td></tr>
<tr><td>5</td><td>3547</td><td>4051</td><td>4859</td></tr>
</tbody></table></body></html>