0

我正在向我自己的个人工具包库中添加一个函数来进行简单的 CSV 到 HTML 表的转换。

我希望用尽可能小的代码在 C# 中执行此操作,并且它需要能够处理超过 ~500mb 的 CSV 文件。

到目前为止,我的两个竞争者是

  • 通过分隔符将 csv 拆分为数组并构建 HTML 输出

  • 使用 table th tr td 标签搜索替换分隔符

假设已经处理了文件/读取/磁盘操作...即,我将包含所述CSV 内容的字符串传递给此函数。输出将包含直接的简单 HTML 无样式标记,是的,数据中可能有杂散的逗号和中断。

更新: 有些人问。如果有帮助的话,我处理的 CSV 100% 直接来自 excel。

示例字符串:

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

3 回答 3

7

将所有行读入内存

    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>");
    }

... @Jimmy ...我使用 LINQ 创建了一个扩展版本。这是亮点......(用于行阅读的懒惰评估)

    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]);
于 2009-06-08T20:55:57.370 回答
2

可能不会比这更短,但请记住,任何真正的解决方案都会处理引号、引号内的逗号以及到 html 实体的转换。

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

编辑:这里(大部分未经测试)添加了 htmlencode 和引号匹配。我先 htmlencode,然后所有逗号都变成 '<' (不会发生冲突,因为现有的逗号已经被编码。

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>";
于 2009-06-08T22:50:52.567 回答
1

Here's a fun version using lambda expressions. It's not as short as replacing commas with "</td><td>", but it has it's own special charm:

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();

If I were to right this for production, I'd use a state machine to track nested quotes, newlines, and commas, because excel can put new lines in the middle of column. IIRC you can also specify a different delimiter entirely.

于 2009-06-09T02:57:22.240 回答