简体   繁体   English

如何将 HTML 表加载到 swing JTable?

[英]How do I load an HTML table to a swing JTable?

The HTML table input doesn't have TH for table headers and has TD with bold text instead HTML 表输入没有表头的 TH,而是使用粗体文本的 TD

It looks like this:它看起来像这样:

<html>
<body>
<table>
<tr>
<td>
<b>column1</b>
</td>
<td>
<b>column2</b>
</td>
<td>
<b>column3</b>
</td>
</tr><tr>
<td>
value1
</td>
<td>
value2
</td>
<td>
value3
</td>
</tr>
</table>
</html>

So I would like the HTML table headers to processed as JTable columns and the other TDs after the first table row to be processed as JTable cells.因此,我希望将 HTML 表头处理为 JTable 列,并将第一个表行之后的其他 TD 处理为 JTable 单元格。

I chose to use this parser as a maven dependency我选择将此解析器用作 maven 依赖项

        <dependency>
            <groupId>org.htmlparser</groupId>
            <artifactId>htmlparser</artifactId>
            <version>2.1</version>
        </dependency>

I invoked the SAX parser like this:我像这样调用 SAX 解析器:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class TestHTML {

    public static void main(String[] args) throws IOException, SAXException {
        org.xml.sax.XMLReader reader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader("org.htmlparser.sax.XMLReader");
        HTMLTableContentHandler htmlTableContentHandler = new HTMLTableContentHandler();
        reader.setContentHandler(htmlTableContentHandler);
        String userDir = System.getProperty("user.home");
        byte[] contents = Files.readAllBytes(Paths.get(userDir, "test.html"));
        reader.parse(new InputSource(new ByteArrayInputStream(contents)));
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new JScrollPane(new JTable(htmlTableContentHandler.getRowData(), htmlTableContentHandler.getColumnNames())));
            frame.pack();
            frame.setVisible(true);
        });
    }
}

The content handler fills the arrays for the JTable as it goes through the SAX events:内容处理程序在通过 SAX 事件时为 JTable 填充 arrays:

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class HTMLTableContentHandler extends DefaultHandler {

    private List<Object> columnNames = new ArrayList<>();
    private List<Object[]> rowData = new ArrayList<>();
    private StringBuilder content = new StringBuilder();
    private int rowIndex;
    private int colIndex;
    private boolean readingColumnName;
    private boolean readingCell;

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if ("B".equals(localName) && rowIndex == 0) {
            if (readingColumnName) {
                columnNames.add(content.toString().trim());
                readingColumnName = false;
            } else {
                readingColumnName = true;
            }
        }
        if ("TD".equals(localName) && rowIndex > 0) {
            readingCell = true;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (readingColumnName || readingCell) {
            content.append(ch, start, length);
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("TR".equals(localName)) {
            rowIndex++;
            colIndex = 0;
        }
        if ("TD".equals(localName) && rowIndex > 0) {
            if (colIndex == 0) {
                rowData.add(new Object[columnNames.size()]);
            }
            rowData.get(rowIndex - 1)[colIndex++] = content.toString().trim();
            readingCell = false;
        }
        content.setLength(0);
    }

    public Object[] getColumnNames() {
        return columnNames.toArray();
    }

    public Object[][] getRowData() {
        return rowData.toArray(new Object[0][]);
    }
}

If you want to use standard classes of the JDK you could do something like:如果您想使用 JDK 的标准类,您可以执行以下操作:

import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;

public class ParserCallbackTable extends HTMLEditorKit.ParserCallback
{
    private boolean tableFound = false;

    private Vector<Object> columnNames;
    private Vector<Vector<Object>> data = new Vector<Vector<Object>>();

    private Vector<Object> row;

    public ParserCallbackTable(String uri)
    {
        try
        {
            Reader reader = getReader( uri );
            new ParserDelegator().parse(reader, this, true);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public void handleStartTag(HTML.Tag tag, MutableAttributeSet a, int pos)
    {
        if ("table".equals(tag.toString()))
            tableFound = true;

        if ("tr".equals(tag.toString()))
            row = new Vector<Object>();
    }

    public void handleEndTag(HTML.Tag tag, int pos)
    {
        if ("table".equals(tag.toString()))
            tableFound = false;

        if ("tr".equals(tag.toString()))
        {
            if (columnNames == null) // first row of data is the column names
                columnNames = row;
            else
                data.add( row );
        }
    }

    public void handleText(char[] data, int pos)
    {
        if (tableFound)
            row.add( new String(data) );
    }

    public TableModel getModel()
    {
        return new DefaultTableModel(data, columnNames);
    }

    private Reader getReader(String uri) throws IOException
    {
        if (uri.startsWith("http")) // Retrieve from Internet
        {
            URLConnection conn = new URL(uri).openConnection();
            return new InputStreamReader(conn.getInputStream());
        }
        else // Retrieve from file
        {
            return new FileReader(uri);
        }
    }

    public static void main(String[] args) throws IOException
    {
        ParserCallbackTable parser = new ParserCallbackTable( args[0] );
        JTable table = new JTable( parser.getModel() );

        JFrame frame = new JFrame("HTML to JTable");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new JScrollPane(table) );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }
}

Just pass the name of you HTML file for a quick test.只需传递您的名称 HTML 文件即可进行快速测试。 For example:例如:

java ParserCallbackTable table.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何获取要在 JTable 中显示的图像 java swing - How do I get a an image to display in JTable in java swing 当用户单击标题时,如何防止对Java Swing JTable列进行排序? - How do I prevent a Java Swing JTable column from being sorted when the user click on the header? 如何使用标题作为第一列创建Java Swing JTable,而不是第一行? - How do I create a Java Swing JTable with header as first column, not as first row? "<i>Java Swing JTable;<\/i> Java Swing JTable;<\/b> <i>Right Click Menu (How do I get it to &quot;select&quot; aka highlight the row)<\/i>右键单击菜单(如何让它“选择”也就是突出显示该行)<\/b>" - Java Swing JTable; Right Click Menu (How do I get it to "select" aka highlight the row) 如何将Web服务返回的集合(ArrayList)绑定到Swing中的JTable? - How do I Bind a Collection (ArrayList) returned by a Web Service to JTable in Swing? SWING JTable:如何使每一行与它的最高对象一样高? - SWING JTable: How do I make each row as high as it's tallest object? 使用Swing JTable重绘表问题 - Repaint Table issue with Swing JTable 如何在JTable中渲染JTable? - How do I render a JTable inside of a JTable? 如何设置和获取JavaFX Table的单元格值(如swing JTable) - How to set and get the cell value of JavaFX Table like swing JTable 如何加快内置表排序的JTable? - How do I speed up JTable built in table sorting?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM