2013-07-03 146 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(); 

} 
    } 
} 
相關問題