【问题标题】:Import data from html file to sql database [closed]将数据从html文件导入sql数据库[关闭]
【发布时间】:2013-07-01 05:53:00
【问题描述】:

我正在尝试了解从 html 表中提取数据并将其导入 sql 表的正确或最佳方法。每周我们都会收到一个 html 文档,我必须将其插入到表格中。我通常只是使用sql管理将其导入空白表,然后将其与当前表合并。我知道一些 c#,所以我想创建一个导入器来自动化一点。

我正在考虑只阅读每一行,然后像这样查找并插入数据。这是最好的方法,还是有更好的方法?

谢谢

这是 html 文件的示例。第一列是列名。

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
    br
    {mso-data-placement:same-cell;}
</style>
</head>
<body>
<table border="1">
<tr><td><b>#</b></td>
<td><b>Asset Manager</b></td>
<td><b>Billing Address</b></td>
<td><b>Billing City</b></td>
<td><b>Billing State</b></td>
<td><b>Billing Zip Code</b></td>
<td><b>Contract Amount</b></td>
<td><b>DUNS Number</b></td>
<td><b>FEIN</b></td>
</tr>
<tr>
<td>1</td>
<td  style="mso-number-format:\@">Jim Bob</td>
<td  style="mso-number-format:\@">2500 N. Park Pkwy, Suite 600</td>
<td  style="mso-number-format:\@">Plano</td>
<td>Texas</td>
<td  style="mso-number-format:\@">75093</td>
<td>$0.00</td>
<td  style="mso-number-format:\@"></td>
<td  style="mso-number-format:\@"></td>
</tr>

</table>
</body>
</html>

到目前为止,我创建了一个用于获取文档名称的按钮。还将 SQLConnection 设置为正确的服务器。

private void buttonBrowse_Click(object sender, EventArgs e)
{
        var DB = new System.Windows.Forms.OpenFileDialog();
        if (DB.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            string fileToOpen = DB.FileName;
            textBoxImport.Text = fileToOpen;

        }
    }

【问题讨论】:

  • 这是我的一个老问题的链接,它解释了如何使用 html 敏捷包解析表:stackoverflow.com/questions/655603/…
  • 感谢您的链接。我在搜索时没有看到那个。

标签: c# html sql


【解决方案1】:

这就是您如何将 HTML 表格的内容加载到数据表中,然后您可以从数据表更新您的真实表格...这可能是一个好的开始,试一试,您可以复制粘贴它作为控制台应用程序运行

namespace ConsoleApplication4   {
    class Program
{
    static void Main(string[] args)
    {
        XmlDocument doc = new XmlDocument();

    doc.LoadXml(@"<table border='1' cellpadding='0' cellspacing='0'>
                <tr>
                <td width='50%'>cell 1a</td>
                <td width='50%'>cell 1b</td>
                </tr>
                <tr>
                <td width='50%'>cell 2a</td>
                <td width='50%'>cell 2b</td>
                </tr>
                </table>");

    DataTable dt = new DataTable();

    dt.Columns.Add("Col1");

    dt.Columns.Add("Col2");

    foreach (XmlNode ndRow in doc.DocumentElement.ChildNodes)
    {
    DataRow dr = dt.NewRow();
    for (int colIndex = 0; colIndex < ndRow.ChildNodes.Count; colIndex++)
    dr[colIndex] = ndRow.ChildNodes[colIndex].InnerText;
    dt.Rows.Add(dr);
    }

    foreach (DataRow r in dt.Rows) {
        Console.Write(r[0] + " --- " + r[1] );
        Console.WriteLine("");
    }

    Console.ReadLine();

}
    }
}

【讨论】:

    【解决方案2】:

    正如其他人提到的,您可以使用HtmlAgilityPack

    这是一个例子:

    DTO:

    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
        public decimal Amount { get; set; }
        // etc
    }
    

    用法:

    var data = @"<html>
    <head>
        <meta http-equiv=""Content-Type"" content=""text/html; charset=UTF-8"" >
    <style>
        br
        {mso-data-placement:same-cell;}
    </style>
    </head>
    <body>
    <table border=""1"">
    <tr><td><b>#</b></td>
    <td><b>Asset Manager</b></td>
    <td><b>Billing Address</b></td>
    <td><b>Billing City</b></td>
    <td><b>Billing State</b></td>
    <td><b>Billing Zip Code</b></td>
    <td><b>Contract Amount</b></td>
    <td><b>DUNS Number</b></td>
    <td><b>FEIN</b></td>
    </tr>
    <tr>
    <td>1</td>
    <td  style=""mso-number-format:\@"">Jim Bob</td>
    <td  style=""mso-number-format:\@"">2500 N. Park Pkwy, Suite 600</td>
    <td  style=""mso-number-format:\@"">Plano</td>
    <td>Texas</td>
    <td  style=""mso-number-format:\@"">75093</td>
    <td>$0.00</td>
    <td  style=""mso-number-format:\@""></td>
    <td  style=""mso-number-format:\@""></td>
    </tr>
    
    </table>
    </body>
    </html>";
    
    string xmlData;
    
    // Create the document   
    var document = new HtmlDocument();
    document.LoadHtml(data);
    document.OptionOutputAsXml = true;
    
    // Write it to Xml so we can use XDocument Linq
    using(var stream = new StringWriter())
    using(var writer = XmlWriter.Create(stream))
    {
        document.Save(writer);
        xmlData = stream.ToString();
    }
    
    // Use XDocument Linq to parse the xml into Customer objects
    var customers = 
        XDocument.Parse(xmlData)
                .XPathSelectElements("//table/tr")
                .Skip(1)
                .Select(x => new Customer {
                    Id     =     int.Parse(x.Elements("td").First().Value),
                    Name   =               x.Elements("td").Skip(1).First().Value,
                    Address=               x.Elements("td").Skip(2).First().Value,
                    City   =               x.Elements("td").Skip(3).First().Value,
                    State  =               x.Elements("td").Skip(4).First().Value,
                    Zip    =               x.Elements("td").Skip(5).First().Value,
                    Amount = decimal.Parse(x.Elements("td").Skip(6).First().Value,
                                           System.Globalization.NumberStyles.Currency)
                });
    

    【讨论】:

    • 非常感谢您提供的示例。它阐明了 HTML Agility Pack 的工作原理。 style="mso-number-format:\@ 是否会影响解析器?
    • 使用 HtmlAgilityPack 没有问题。 Meta 标签是无效的 Xml,所以 HtmlAgilityPack 可以解决这些常见问题。
    • 我想对此进行测试,并在解析后将标签设置为 Id 值。但据我所知,价值是一个非静态属性。如何在静态方法中设置它?这可能很简单,但由于某种原因,我的大脑一片空白。
    • +1 用于创建工作示例!
    • @Cory 更多人应该在他们的第二个/第三个显示器上打开 Linqpad。
    【解决方案3】:

    如果您必须接收 HTML 格式的文件,我会研究可以将 HTML 解析为可用文档结构的第三方库(例如 HTMLAgilityPack)。

    使用库,您可以遍历文档并从节点中提取值,而无需尝试使用丑陋的代码来解析它们。

    我将首先创建一个代表表中一行的类。给它代表表格标题的属性。然后使用 HTML 库获取您想要的值并创建该类的实例,设置属性值,并将它们添加到集合中。

    最后,打开与数据库的连接。循环遍历类的集合并使用prepared statements将它们的数据一一插入到您的数据库中。

    使用SqlConnection 类时,请确保应用正确的处理技术并利用using 语句,以便很好地清理您的连接。

    【讨论】:

    • 这就是我每次收到html文档的方式。但是感谢第三方库。我会毫不犹豫地考虑使用它。
    • 遍历每个节点时。我有一些td有“style =”mso-number格式:\ @“添加,而有些则是。选择单个时,我需要查找两者,或者只是说TD它会将其放在一起添加的样式属性?
    • 只是 应该没问题。如果您发现需要同时查找两者,则应该有一种方法(通过 xpath 或其他方式)来过滤存在该属性的节点。
    【解决方案4】:

    适合解析 HTML 的是 HtmlAgility Pack。 Here

    【讨论】:

    • 谢谢。我去看看。
    【解决方案5】:

    您可以使用 HtmlAgilityPack 解析 Html 并将其读入 DataTable 对象。如果要传输大量数据,则可以使用常规插入或 SqlBulkCopy 轻松将 DataTable 写入数据库。

    【讨论】:

    • 谢谢。我会检查 HtmlAgilityPack。在发布之前进行搜索,我从未见过任何人建议。谢谢
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签