如何从html表及其内部表中提取数据?

时间:2015-08-01 11:56:36

标签: java html jsoup

我有一个html表结构,在主表中有一些数据,有些在td元素内的嵌套表中。

我只想要所需的5个数据(带** xx **指示),这样我就可以将它作为单行导出到Excel。

<table cellpadding="2" cellspacing="0" width="100%" class="chart">
              <tr>
              <td>**Text 1**</td>         
                <td>
                  <table cellpadding="2" cellspacing="0">
                    <tr>
                      <td>some useless data</td>
                      <td>**Text 2**</td>
                    </tr>
                  </table>
                </td>
                <td>**Text 3**</td>
                <td>**Text 4**</td>
                <td>**Text 5**</td>
              </tr>
</table>

我的代码是这样的:

    for (Element row : excel.select("tr")) {
        // create row for each tag
        header = sheet.createRow(rowCount);
        // loop through all th tag
        Elements ths = row.select("th");
        int count = 0;
        for (Element element : ths) {
            // set header style
            cell = header.createCell(count);
            cell.setCellValue(element.text());
            cell.setCellStyle(headerStyle);
            count++;
        }
        // now loop through all td tag
        Elements tds = row.select("td");
        count = 0;
        for (Element element : tds) {
            if(!element.text().isEmpty()){
                cell = header.createCell(count);
                cell.setCellValue(element.text());
                count++;
                }
        }

这里的问题是输出不符合预期。

在Excel中看起来像这样:

  Row1:  Text 1 | Text 2 | useless data | Text 2 | Text 3 | Text 4 | Text 5 |
  Row2:  useless data | Text 2 |

附加信息:为简化问题,省略了标签。

我想要的是

 Row1:  Text 1 | Text 2 | Text 3 | Text 4 | Text 5 |

1 个答案:

答案 0 :(得分:1)

<强> 1。两行

我猜excel是文档或表格。无论如何,当你选择 excel.select("tr")您还会选择内部表格tr。要防止这种情况,您需要使css选择器更具体。如果我假设excel是文档,我可以这样做

Elements outerTrs = excel.select("table.chart>tbody>tr");

在您的代码的上下文中:

for (Element row : excel.select("table.chart>tbody>tr")) {

说明: 如果表中没有Jsoup,则会在表中创建tbody元素。使用选择器我确保只选择直接子tr外部表的元素,我可以这样做,因为我知道外表的类名,它看起来很独特。

<强> 2。意外的列数

这是因为您的select row.select("td")语句选择了包含内部表的td。如果你只想要没有子元素的tds,你可以使用它:

Elements tds = row.select("td");
count = 0;
for (Element element : tds) {
if(!element.text().isEmpty() && element.children().isEmpty()){
    count++;
    System.out.println("line "+count+" text = '"+element.text()+"'");
}

第3。无用的数据

要摆脱这种情况,您需要将其过滤掉。从您的示例中,不清楚何时存在无用数据。它始终是内表中的第一个td吗?如果是这样,你可以这样做(完整的解决方案)

Document excel = Jsoup.parse(tab);

for (Element row : excel.select("table.chart>tbody>tr")) {
    Elements tds = row.select("td");
    int count = 0;

    Element junkTd = row.select("td table td").first();

    for (Element element : tds) {
        if(!element.text().isEmpty() 
                && element.children().isEmpty()
                && !element.equals(junkTd)){

            count++;
            System.out.println("line "+count+" text = '"+element.text()+"'");
        }
    }
}