PHP :: Aufgabe #3
3 Lösungen
CSV-Datei auslesen und aus den Daten eine Tabelle und ein Diagramm erzeugen
Fortgeschrittener - PHP
von Gustl
- 16.08.2012 um 10:35 Uhr
Erstellen Sie ein PHP- Skript, das die angehängte CSV- Datei (EUR/USD Dollarkurs von einem Jahr) in ein Array einliest. Diese eingelesenen Werte sollen in einer Tabelle dargestellt werden und sich in einem Linien-, Punkt- oder Balkendiagramm widerspiegeln.
In dem Diagramm soll nur jeder vierte Wert ausgegeben werden.
Das Datum soll in folgendes Format konvertiert werden: DD.MM.YY (16.08.12)
In dem Diagramm soll nur jeder vierte Wert ausgegeben werden.
Das Datum soll in folgendes Format konvertiert werden: DD.MM.YY (16.08.12)
Lösungen:
<?php
class Csv
{
protected $csvArray = array();
protected $htmlTable = '';
public function __construct( $file )
{
$this->importCsvData( $file );
$this->makeTable( $this->csvArray );
}
protected function importCsvData( $file )
{
$handle = fopen( $file, 'r' );
while( ($line = fgetcsv( $handle, 0, ';' )) !== FALSE ){
$this->csvArray[] = $line;
}
fclose($handle);
$this->csvArray = $this->modifyArray( $this->csvArray );
}
protected function modifyArray( array$array )
{
foreach ( $array as &$subarray ) {
$keys = array_keys( $subarray, NULL );
foreach ( $keys as $key ) {
unset( $subarray[$key] );
}
if ( isset($subarray[0]) ) {
$subarray[0] = $this->formatDate( $subarray[0] );
}
}
return $array;
}
protected function formatDate( $date )
{
if ( $this->isValidDate( $date ) ) {
$oDateTime = new DateTime( $date );
return $oDateTime->format( 'd.m.y' );
}
return $date;
}
protected function isValidDate( $str )
{
$stamp = strtotime( $str );
if (!is_numeric($stamp))
{
return FALSE;
}
$month = date( 'm', $stamp );
$day = date( 'd', $stamp );
$year = date( 'Y', $stamp );
if (checkdate($month, $day, $year))
{
return TRUE;
}
return FALSE;
}
protected function makeTable( array$array )
{
$html = '<table>';
foreach ( $array as $subarray ) {
$html .= '<tr>';
foreach ( $subarray as $value ) {
$html .= '<td>' . $value . '</td>';
}
$html .= '</tr>';
}
$html .= '</table>';
$this->htmlTable = $html;
}
public function printArray()
{
return $this->csvArray;
}
public function printTable()
{
return $this->htmlTable;
}
}
$csv = new Csv( 'csv.csv' );
echo $csv->printTable();
Das mit dem Diagramm habe ich jetzt nicht verstanden... soll das auch mit PHP umgesetzt werden?
Code kann so kopiert werden, wie er ist.
Zu beachten:
- Alles in eine Datei rein
- CSV Datei muss im selben Verzeichnis sein und entsprechend benannt sein (Zeile 5)
PHP-Code
Zu beachten:
- Alles in eine Datei rein
- CSV Datei muss im selben Verzeichnis sein und entsprechend benannt sein (Zeile 5)
<?php
try
{
$myCsv = new Csv('data.csv');
if(!isset($_POST['graph']))
{
$myCsv->printTable();
}
else
{
$graph = new Graph(500, 500, $myCsv->getData());
$graph->print();
}
}
catch (Exception $ex)
{
echo $ex->getMessage();
}
class Csv
{
private $Path;
private $Data;
private $Keys;
public function getData() { return $this->Data; }
public function getKeys() { return $this->Keys; }
public function Csv($path)
{
if(!file_exists($path))
{
throw new Exception('Datei existiert nicht.');
}
try
{
$this->Path = $path;
$this->Data = array();
$rawdata = file($this->Path);
if(sizeof($rawdata) == 0)
{
throw new Exception('Keine Daten vorhanden.');
}
$this->prase($rawdata);
}
catch (Exception $ex)
{
throw new Exception($ex);
}
}
private function prase($rawdata)
{
$this->Keys = explode(';', array_shift($rawdata));
for ($index=0; $index < sizeof($rawdata); $index++)
{
$temp = explode(';', $rawdata[$index]);
array_push($this->Data, new Record($temp[0], preg_replace('%\,%', '', $temp[1]), preg_replace('%\,%', '', $temp[2]), preg_replace('%\,%', '', $temp[3]), preg_replace('%\,%', '', $temp[4])));
}
}
public function printTable()
{
echo '<div style="float:left;"><table>';
echo $this->printTableHead();
echo $this->printTableBody();
echo '</table></div>';
}
private function printTableHead()
{
$head = '<thead><tr>';
foreach ($this->Keys as $key)
{
$head .= '<th>'.$key.'</th>';
}
$head .= '</tr></thead>';
return $head;
}
private function printTableBody()
{
$body = '<tbody>';
foreach ($this->Data as $data)
{
$body .= '<tr>';
$values = $data->getAttributes();
foreach ($values as $value)
{
$body .= '<td>'.$value.'</td>';
}
$body .= '</tr>';
}
$body .= '</tbody>';
return $body;
}
}
class Graph
{
private $Width;
private $Height;
private $Data;
private $Canvas;
private $Color;
private $EveryNthPoint;
private $AmoundGrids;
public function Graph($w, $h, $d, $m = 25, $p = 10, $g = 20)
{
$this->Width = $w;
$this->Height = $h;
$this->Margin = $m;
$this->Data = $d;
$this->EveryNthPoint = $p;
$this->AmoundGrids = $g;
$this->InitCanvas();
$this->InitColors();
}
private function InitCanvas()
{
$this->Canvas = imagecreatetruecolor($this->Width, $this->Height);
}
private function InitColors()
{
$this->Color['black'] = imagecolorallocate($this->Canvas, 0, 0, 0);
$this->Color['white'] = imagecolorallocate($this->Canvas, 255, 255, 255);
$this->Color['red'] = imagecolorallocate($this->Canvas, 255, 0, 0);
$this->Color['gray'] = imagecolorallocate($this->Canvas, 127, 127, 127);
}
private function getMax()
{
$max = (int)$this->Data[0]->getAttributes()['closingprice'];
for ($index=1; $index < sizeof($this->Data); $index++)
{
if($max < (int)$this->Data[$index]->getAttributes()['closingprice'])
{
$max = (int)$this->Data[$index]->getAttributes()['closingprice'];
}
}
return $max;
}
private function CreateGrid()
{
$this->Width -= $this->Margin;
$this->Height -= $this->Margin;
$x1 = $this->Margin;
$x2 = $this->Width;
$y1 = $this->Margin;
$y2 = $this->Height;
while($y1 < $this->Height)
{
imageline($this->Canvas, $x1, $y1, $x2, $y1, $this->Color['gray']);
$y1 += $this->Height / $this->AmoundGrids;
}
$y1 = 0;
while($x1 < $this->Width)
{
imageline($this->Canvas, $x1 , $y1 + $this->Margin, $x1, $y2, $this->Color['gray']);
$x1 += $this->Width / $this->AmoundGrids;
}
imagerectangle($this->Canvas, $this->Margin, $this->Margin, $this->Width, $this->Height, $this->Color['black']);
}
public function Print()
{
$x1 = $this->Margin - 2.5;
$x2 = $x1 + 5;
$y1;
$y2;
$last_x = -1;
$last_y = -1;
$scaleY = ($this->Height - $this->Margin) / $this->getMax();
imagefilledrectangle($this->Canvas, 0, 0, $this->Width, $this->Width, $this->Color['white']); // hintergrund
$this->CreateGrid();
for ($index=0; $index < sizeof($this->Data); $index++)
{
if($index % $this->EveryNthPoint == 0)
{
$y1 = (int)$this->Data[$index]->getAttributes()['closingprice'] * $scaleY;
$y2 = $y1 + 5;
imagefilledrectangle($this->Canvas, $x1, $y1, $x2, $y2, $this->Color['red']);
$x1 += ($this->Width - $this->Margin) / ((sizeof($this->Data) / $this->EveryNthPoint));
$x2 = $x1 + 5;
}
}
header('Content-Type: image/jpeg');
imagejpeg($this->Canvas);
imagedestroy($this->Canvas);
}
}
class Record
{
private $date;
private $first;
private $high;
private $low;
private $closingprice;
public function Record($date_, $first_, $high_, $low_, $closingprice_)
{
$this->date = $this->convertDate($date_);
$this->first = $first_;
$this->high = $high_;
$this->low = $low_;
$this->closingprice = $closingprice_;
}
public function getAttributes()
{
return get_object_vars($this);
}
private function convertDate($date)
{
return date('d.m.y', strtotime($date));
}
}
?>
<html>
<head>
<style>
table
{
border-collapse: collapse;
}
table, th, td
{
border: 1px solid black;
padding: 5px;
}
th
{
background-color: silver;
}
button
{
width: 50%;
height: 100px;
margin-left: 1%;
font-family: Arial;
font-size: 50;
}
</style>
</head>
<body>
<form method="post">
<button type="submit" name="graph">Diagramm erstellen!</button>
</form>
</body>
</html>
<!DOCTYPE html> <html> <head> <title>CSV</title> <meta charset="utf-8"> </head> <body> <form method="POST" style="margin-bottom:10px;"> <fieldset> <legend>Diagramm oder Tabelle?</legend> <input type="text" name="eingabe"> <br><br> <input type="submit" name=""> </fieldset> </form> </body> </html>
<?php
if(isset($_POST['eingabe']))
{
$filepath = "C:\\xampp\\htdocs\\PHP_scripts\\eukurs.csv";
$standardarray = getCSVinArray($filepath);
if(strtolower($_POST['eingabe']) == "diagramm")
{
CSVtoDiagram($standardarray);
}
else if(strtolower($_POST['eingabe']) == "tabelle")
{
CSVtoTable($standardarray);
}
else
{
echo "Es wurde keine der beiden Optionen gewählt! Tippen Sie in das Textfeld \"Diagramm\" oder \"Tabelle\" ein!";
}
}
function getCSVinArray($path)
{
$temparray = file($path);
$valuearray[] = array();
for($i = 0; $i < count($temparray); $i++)
{
$valuearray[$i] = explode(";", $temparray[$i]);
}
return $valuearray;
}
function CSVtoTable($array)
{
echo "<style>table{width:100%;}td,th{padding:8px;text-align:left;border:1px solid #dddddd;</style>";
echo "<table>
<tr>
<th>". $array[0][0] ."</th>
<th>". $array[0][1] ."</th>
<th>". $array[0][2] ."</th>
<th>". $array[0][3] ."</th>
<th>". $array[0][4] ."</th>
</tr>";
for($j = 1; $j <= count($array)-1; $j++)
{
$timestamp = strtotime($array[$j][0]);
$newtime = date('d.m.y', $timestamp);
echo "<tr>
<td>". $newtime ."</td>
<td>". $array[$j][1] ."</td>
<td>". $array[$j][2] ."</td>
<td>". $array[$j][3] ."</td>
<td>". $array[$j][4] ."</td>
</tr>";
}
echo "</table>";
}
function CSVtoDiagram($array)
{
$countbalken = count($array);
while($countbalken % 4 != 0)
{
$countbalken -= 1;
}
echo "<svg width=\"100%\" height=\"500\" style=\"border: 1px solid black;\">";
$i = 0;
$x = 0;
while($i <= $countbalken)
{
if($i != 0)
{
$temp = $array[$i][4];
$float = floatval(str_replace(",", ".", $temp)) * 300;
echo "<rect id=\"" . $i ."\" x=\"" . $x . "\" y=\"0\" width=\"6\" height=\"" . $float . "\" style=\"fill:rgb(0,0,255);stroke:black;\" />";
$x += 15;
}
$i += 4;
}
echo "</svg>";
}
?>