2013-07-03 97 views
1

我想了解什么是正确或最好的方式从一个HTML表中拉出数据并将其导入到一个SQL表。每周我们都会得到一个html文档,我必须将其插入表格中。我通常只是使用SQL管理将其导入到一个空白表中,然后将其与当前表合并。我知道一些C#,所以我想创建一个导入器来自动化一下。从HTML文件导入数据到SQL数据库

我正在考虑只读每一行,并通过寻找并插入数据。这是最好的方式,还是有更好的方法来做到这一点?

谢谢

这里是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; 

     } 
    } 
+0

这是一个链接到我的老问题,它解释了如何使用html敏捷包解析表:http://stackoverflow.com/questions/655603/html-agility-pack-parsing-tables。 – weismat

+0

感谢您的链接。我在搜索时没有看到那一个。 – Zach

回答

3

正如其他人提到你可以使用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) 
      }); 
+0

非常感谢你的例子。它清除了HTML敏捷包的工作方式。style =“mso-number-format:\ @扔掉解析器吗? – Zach

+0

使用HtmlAgilityPack没有问题。 Meta标签不是有效的Xml,所以'HtmlAgilityPack'可以解决这些常见的问题。 – Romoku

+0

我想测试这个,只是在解析后将标签设置为Id值。但据我所知,价值是一个非静态属性。如何设置静态方法?这可能很简单,但由于某种原因,我的想法是空白。 – Zach

0

你可以使用HtmlAgilityPack解析HTML和读入一个DataTable对象。如果要传输大量数据,则可以使用常规插入或SqlBulkCopy轻松地将DataTable写入数据库。

+0

谢谢。我会检查HtmlAgilityPack。在我发布之前搜索,我从来没有看到任何人的建议。谢谢 – Zach

1

适用于解析HTML的是HtmlAgility Pack。 Here

+0

谢谢。我会看看。 – Zach

1

如果必须接收HTML格式的文件,我会考虑这样做可以解析HTML成可用的文件结构(例如在HTMLAgilityPack)第三方库。

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

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

最后,打开一个连接到您的数据库。循环使用准备的语句将类的集合逐个插入到数据库中。

使用SqlConnection类时,请确保使用适当的处理技巧并利用using语句,以便您的连接得到良好的清理。

+0

这就是我每次收到html文档的方式。但是感谢第三方库。我会反对使用它。遍历每个节点时,可以使用 – Zach

+0

。我有一些td有“style =”mso-number-format:\ @“的补充,有些是​​。选择单个节点时,我需要寻找两个,还是只要说TD就会把它放到风格添加属性 – Zach

+0

只要​​应该没问题如果你发现你需要查找这两者,应该有一种方法(通过xpath或其他方式)来过滤该属性存在的节点 –

0

这是你怎么能一个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(); 

} 
    } 
} 
相关问题