tags:

views:

2492

answers:

3

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.

A: 

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();
                    }
                };
            }
        };
    }
}
Kevin
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.
dreeves
+5  A: 

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>";
phihag
Brilliant! Thank you so much. I think I'll go ahead and remove that link from the question then.
dreeves
A: 

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'

Scott Evernden
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.
dreeves