Codegolf: конвертировать CSV в HTML-таблицу с наименьшим количеством кода в C # - PullRequest
0 голосов
/ 09 июня 2009

Я добавляю функцию в свою собственную библиотеку инструментария для простого преобразования таблицы CSV в HTML.

Я бы хотел, чтобы наименьший возможный кусок кода делал это на C # , и он должен иметь возможность обрабатывать файлы CSV, превышающие ~ 500 МБ.

Пока что мои два соперника

  • разбиение CSV на массивы по разделители и построение вывода HTML

  • поиск-замена разделителей с таблицей th tr td теги

Предположим, что операции с файлом / чтением / диском уже обработаны ... то есть я передаю строку, содержащую содержимое указанного CSV, в эту функцию. Вывод будет состоять из простой простой разметки в стиле HTML, и да, данные могут иметь запятые и разрывы в них.

обновление: спросили некоторые люди. 100% CSV, с которыми я работаю, получаются просто превосходными, если это поможет.

Пример строки:

a1,b1,c1\r\n
a2,b2,c2\r\n

Ответы [ 3 ]

6 голосов
/ 09 июня 2009

Читать все строки в памяти

    var lines =File.ReadAllLines(args[0]);
    using (var outfs = File.AppendText(args[1]))
    {
        outfs.Write("<html><body><table>");
        foreach (var line in lines)
            outfs.Write("<tr><td>" + string.Join("</td><td>", line.Split(',')) + "</td></tr>");
        outfs.Write("</table></body></html>");
    }

или чтение по одной строке за раз

    using (var inFs = File.OpenText(args[0]))
    using (var outfs = File.AppendText(args[1]))
    {
        outfs.Write("<html><body><table>");
        while (!inFs.EndOfStream )
            outfs.Write("<tr><td>" + string.Join("</td><td>", inFs.ReadLine().Split(',')) + "</td></tr>");
        outfs.Write("</table></body></html>");
    }

... @ Джимми ... Я создал расширенную версию, используя LINQ. Вот основной момент ... (ленивый eval для чтения строк)

    using (var lp = args[0].Load())
        lp.Select(l => "<tr><td>" + string.Join("</td><td>", l.Split(',')) + "</td></tr>")
        .Write("<html><body><table>", "</table></body></html>", args[1]);
2 голосов
/ 09 июня 2009

возможно, вы не намного короче, чем это, но просто помните, что любое реальное решение будет обрабатывать кавычки, запятые внутри кавычек и преобразования в HTML-сущности.

return "<table><tr><td>"+s
   .Replace("\n","</td></tr><tr><td>")
   .Replace(",","</td><td>")+"</td></tr></table>";

РЕДАКТИРОВАТЬ: вот (в основном не проверено) добавление htmlencode и сопоставление кавычек. Сначала я htmlencode, затем все запятые становятся '<' (которые не сталкиваются, потому что существующие уже были закодированы. </p>

bool q=false;
return "<table><tr><td>"
  + new string(HttpUtility.HtmlEncode(s)
       .Select(c=>c=='"'?(q=!q)?c:c:(c==','&&!q)?'<':c).ToArray())
    .Replace("<", "</td><td>")
    .Replace("\n", "</td></tr><tr><td>")
  + "</td></tr></table>";
1 голос
/ 09 июня 2009

Вот забавная версия с использованием лямбда-выражений. Он не такой короткий, как замена запятых на "</td><td>", но у него есть свой особый шарм:

var r = new StringBuilder("<table>");
s.Split('\n').ToList().ForEach(t => r.Append("<tr>").Append(t.Split(',').Select(u => "<td>" + u + "</td>")).Append("</tr>"));
return r.Append("</table>").ToString();

Если бы я исправил это для производства, я бы использовал конечный автомат для отслеживания вложенных кавычек, новых строк и запятых, потому что Excel может поставить новые строки в середине столбца. IIRC вы также можете указать другой разделитель полностью.

...