32

I'd like to take a CSV file living server-side and display it dynamically as an html table. E.g., this:

Name, Age, Sex
"Cantor, Georg", 163, M

should become this:

<html><body><table>
<tr> <td>Name</td> <td>Age</td> <td>Sex</td> </tr>
<tr> <td>Cantor, Georg</td> <td>163</td> <td>M</td> </td>
</table></body></html>

Solutions in any language are welcome.

9 Answers 9

107

The previously linked solution is a horrible piece of code; nearly every line contains a bug. Use fgetcsv instead:

<?php
echo "<html><body><table>\n\n";
$f = fopen("so-csv.csv", "r");
while (($line = fgetcsv($f)) !== false) {
        echo "<tr>";
        foreach ($line as $cell) {
                echo "<td>" . htmlspecialchars($cell) . "</td>";
        }
        echo "</tr>\n";
}
fclose($f);
echo "\n</table></body></html>";
Sign up to request clarification or add additional context in comments.

4 Comments

Brilliant! Thank you so much. I think I'll go ahead and remove that link from the question then.
Just want to say, this is best code I've found so far - well done sir!
@phihag. Could you please provide an example to use your code? Thanks in advance
@ddpd You can create a new php file, insert this code, and run it. It's already an example ;)
13

Here is a simple function to convert csv to html table using php:

function jj_readcsv($filename, $header=false) {
$handle = fopen($filename, "r");
echo '<table>';
//display header row if true
if ($header) {
    $csvcontents = fgetcsv($handle);
    echo '<tr>';
    foreach ($csvcontents as $headercolumn) {
        echo "<th>$headercolumn</th>";
    }
    echo '</tr>';
}
// displaying contents
while ($csvcontents = fgetcsv($handle)) {
    echo '<tr>';
    foreach ($csvcontents as $column) {
        echo "<td>$column</td>";
    }
    echo '</tr>';
}
echo '</table>';
fclose($handle);
}

One can call this function like jj_readcsv('image_links.csv',true);

if second parameter is true then the first row of csv will be taken as header/title.

Hope this helps somebody. Please comment for any flaws in this code.

Comments

8

phihag's answer puts each row in a single cell, while you are asking for each value to be in a separate cell. This seems to do it:

<?php
// Create a table from a csv file 
echo "<html><body><table>\n\n";
$f = fopen("so-csv.csv", "r");
while (($line = fgetcsv($f)) !== false) {
        $row = $line[0];    // We need to get the actual row (it is the first element in a 1-element array)
        $cells = explode(";",$row);
        echo "<tr>";
        foreach ($cells as $cell) {
            echo "<td>" . htmlspecialchars($cell) . "</td>";
        }
        echo "</tr>\n";
}
fclose($f);
echo "\n</table></body></html>";
?>

Comments

2

Just improved phihag's code because it runs into a infinite loop if file not exists.

<?php

$filename = "so-csv.csv";

echo "<html><body><table>\n\n";

if (file_exists($filename)) {
$f = fopen($filename, "r");
while (($line = fgetcsv($f)) !== false) {
        echo "<tr>";
        foreach ($line as $cell) {
                echo "<td>" . htmlspecialchars($cell) . "</td>";
        }
        echo "</tr>\n";
}
fclose($f);
}

else{ echo "<tr><td>No file exists ! </td></tr>" ;}
echo "\n</table></body></html>";
?>

Comments

2

Here is the working solution updated with a few bootstrap goodies. Table Small, Striped, Bordered, and Hover Highlight

function jj_readcsv($filename, $header = false)
{
    $handle = fopen($filename, "r");
    echo '<div class="table-responsive"><table class="table table-sm table-striped table-bordered table-hover">';
    //display header row if true
    if ($header) {
        $csvcontents = fgetcsv($handle);
        echo '<tr>';
        foreach ($csvcontents as $headercolumn) {
            echo "<th>$headercolumn</th>";
        }
        echo '</tr>';
    }
    // displaying contents
    while ($csvcontents = fgetcsv($handle)) {
        echo '<tr>';
        foreach ($csvcontents as $column) {
            echo "<td style='width:1px; white-space:nowrap;'>$column</td>";
        }
        echo '</tr>';
    }
    echo '</table></div>';
    fclose($handle);
}

Comments

-1

Does it work if you escape the quoted commas with \ ?

Name, Age, Sex

"Cantor\, Georg", 163,M

Most delimited formats require that their delimiter be escaped in order to properly parse.


A rough Java example:

import java.util.Iterator;

public class CsvTest {

    public static void main(String[] args) {
        String[] lines = { "Name, Age, Sex", "\"Cantor, Georg\", 163, M" };

        StringBuilder result = new StringBuilder();

        for (String head : iterator(lines[0])) {
            result.append(String.format("<tr>%s</tr>\n", head));
        }

        for (int i=1; i < lines.length; i++) {
            for (String row : iterator(lines[i])) {
                result.append(String.format("<td>%s</td>\n", row));
            }
        }

        System.out.println(String.format("<table>\n%s</table>", result.toString()));
    }

    public static Iterable<String> iterator(final String line) {
        return new Iterable<String>() {
            public Iterator<String> iterator() {
                return new Iterator<String>() {
                    private int position = 0;

                    public boolean hasNext() {
                        return position < line.length();
                    }

                    public String next() {
                        boolean inquote = false;
                        StringBuilder buffer = new StringBuilder();
                        for (; position < line.length(); position++) {
                            char c = line.charAt(position);
                            if (c == '"') {
                                inquote = !inquote;
                            }
                            if (c == ',' && !inquote) {
                                position++;
                                break;
                            } else {
                                buffer.append(c);
                            }
                        }
                        return buffer.toString().trim();
                    }

                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }
}

1 Comment

I don't think the sample solution handles that. But I also don't think that escaping the commas should be necessary, since they're in quotes. (Escaping quotes, on the other hand, yes.) For example, mysql exports to CSV without escaped commas.
-1

HTML ... tag can do that itself i.e. no PHP or java.

or see this post for complete detail on the above (with all options..).

http://www.linuxquestions.org/questions/programming-9/how-to-show-csv-data-as-html-in-internet-explorer-with-filter-buttons-4175443612/

Comments

-2

define "display it dynamically" ? that implies the table is being built via javascript and some sort of Ajax-y update .. if you just want to build the table using PHP that's really not what I would call 'dynamic'

1 Comment

Php that generates it server-side per web request was good enough for me. If you have an ajaxy solution it would be great to include it here for others searching for this later.
-2

XmlGrid.net has tool to convert csv to html table. Here is the link: http://xmlgrid.net/csvToHtml.html

I used your sample data, and got the following html table:

<table>
<!--Created with XmlGrid Free Online XML Editor (http://xmlgrid.net)-->
<tr>
  <td>Name</td>
  <td> Age</td>
  <td> Sex</td>
</tr>
<tr>
  <td>Cantor, Georg</td>
  <td> 163</td>
  <td> M</td>
</tr>
</table>

1 Comment

He said "dynamically", your solution doesn't allow for that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.