使用colspan和rowspan从2d数组生成html表

时间:2016-01-12 07:50:27

标签: java html algorithm html-table

我需要从仅包含数据,colspan和rowspan的2d数组生成html表。我不需要边距,高度和宽度。只有td和tr。我知道表格单元格的宽度和高度,结果总是矩形。我需要在java中完成它,但任何提示都是受欢迎的。

以下是一个示例单元类:

public class Cell {

    String label;
    int colSpan, rowSpan;

    public Cell(String label, int colSpan, int rowSpan) {
        this.label = label;
        this.colSpan = colSpan;
        this.rowSpan = rowSpan;
    }

}

以下是包含数据和rowspan / colspan信息的2d数组的示例;

public class Test {

    public static void main(String[] args) {
        List<List<Cell>> rows = new ArrayList<>();

        List<Cell> row1 = new ArrayList<>();
        Cell cell11 = new Cell("total", 1, 9);
        Cell cell12 = new Cell("mid_total", 1, 3);
        Cell cell13 = new Cell("detail", 1, 1);
        row1.add(cell11);
        row1.add(cell12);
        row1.add(cell13);
        rows.add(row1);

        List<Cell> row2 = new ArrayList<>();
        Cell cell21 = new Cell("mid_total", 1, 3);
        Cell cell22 = new Cell("detail", 1, 1);
        row2.add(cell21);
        row2.add(cell22);
        rows.add(row2);

        List<Cell> row3 = new ArrayList<>();
        Cell cell31 = new Cell("mid_total", 1, 3);
        Cell cell32 = new Cell("detail", 1, 1);
        row3.add(cell31);
        row3.add(cell32);
        rows.add(row3);

        List<Cell> row4 = new ArrayList<>();
        Cell cell41 = new Cell("detail", 1, 1);
        row4.add(cell41);
        rows.add(row4);

        List<Cell> row5 = new ArrayList<>();
        Cell cell51 = new Cell("detail", 1, 1);
        row5.add(cell51);
        rows.add(row5);

        List<Cell> row6 = new ArrayList<>();
        Cell cell61 = new Cell("detail", 1, 1);
        row6.add(cell61);
        rows.add(row6);

        List<Cell> row7 = new ArrayList<>();
        Cell cell71 = new Cell("detail", 1, 1);
        row7.add(cell71);
        rows.add(row7);

        List<Cell> row8 = new ArrayList<>();
        Cell cell81 = new Cell("detail", 1, 1);
        row8.add(cell81);
        rows.add(row8);

        List<Cell> row9 = new ArrayList<>();
        Cell cell91 = new Cell("detail", 1, 1);
        row9.add(cell91);
        rows.add(row9);
    }
}

这就是它的样子:

+-------+-----------+--------+
| total | mid_total | detail |
+       +           +--------+
|       |           | detail |
+       +           +--------+
|       |           | detail |
+       +-----------+--------+
|       | mid_total | detail |
+       +           +--------+
|       |           | detail |
+       +           +--------+
|       |           | detail |
+       +-----------+--------+
|       | mid_total | detail |
+       +           +--------+
|       |           | detail |
+       +           +--------+
|       |           | detail |
+-------+-----------+--------+

3 个答案:

答案 0 :(得分:0)

迭代二维数组中的行和列,并使用StringBuilder创建HTML标记。

public String toHTML(String[][] data){
    StringBuilder sb = new StringBuilder();
    sb.append("<table>\n");
    for(int row = 0; row < data.length; row++){
        sb.append("\t<tr>\n");
        for(int col = 0; col < data[0].length; col++){
            sb.append("\t\t<td>" + data[row][col] + "</td>\n");
        }
        sb.append("\t</tr>\n");
    }
    sb.append("</table>");
    return sb.toString();
}

如果你这样使用它:

String[][] data = {{"r0c1", "r0c2", "r0c3"},
                   {"r1c1", "r1c2", "r1c3"}};   
System.out.println(toHTML(data));

它会产生这个:

<table>
    <tr>
        <td>r0c1</td>
        <td>r0c2</td>
        <td>r0c3</td>
    </tr>
    <tr>
        <td>r1c1</td>
        <td>r1c2</td>
        <td>r1c3</td>
    </tr>
</table>

答案 1 :(得分:0)

您可以为单元格创建容器类,以管理多列和多行单元格的正确定位。

您有一个插槽网格,当您放置一个跨越多个列或行的单元格时,您将使此大单元占用的插槽无效,仅在左上角插槽中保留对实际单元格的引用。打印标记时,不要打印无效的单元格。

您似乎自上而下创建表,因此一种自然的方法是跟踪当前行和列,以便插入单元格可以找到下一个可用的单元格。

如果您不想事先确定表格的尺寸或摇晃不断调整大小的单元格,您可以将单元格存储在哈希映射中,并将它们在网格中的位置作为键,以便您可以轻松追加细胞不用担心会溢出桌子。

下面是您的示例表的实现。我对Java并不擅长 - 我缺乏技能和软件 - 所以我在D中写了代码。我认为主要的想法应该是明确的。 D内置了关联数组,V[K]对应于Java java.util.HashMap<K, V>

import std.stdio;
import std.array;
import std.string;

class Cell
{
public:
    this(string _label, int _colSpan, int _rowSpan)
    {
        label = _label;
        colSpan = _colSpan;
        rowSpan = _rowSpan;
    }

    string toHtml() {
        auto app = appender!string();

        app.put("        <td");
        if (colSpan > 1) app.put(format(" colspan='%d'", colSpan));
        if (rowSpan > 1) app.put(format(" rowspan='%d'", rowSpan));
        app.put(">");
        app.put(label);
        app.put("</td>\n");

        return app.data;
    } 

private:
    string label;
    int colSpan;
    int rowSpan;
}

class Table
{
public:
    this() {
    }

    void newRow() {
        row++;
        col = 0;
    }

    void add(string label, int colSpan = 1, int rowSpan = 1)
    {
        assert(row >= 0);
        assert(colSpan > 0);
        assert(rowSpan > 0);

        auto c = new Cell(label, colSpan, rowSpan);

        while (key(col, row) in cell) col++;

        for (int j = 0; j < rowSpan; j++) {
            for (int i = 0; i < colSpan; i++) {
                addCell(col + i, row + j,
                    (i == 0 && j == 0) ? c : null);
            }
        }

        col += colSpan;
    }

    string toHtml() {
        auto app = appender!string();

        app.put("<table>\n");

        for (int y = 0; y < nrow; y++) {
            app.put("    <tr>\n");

            for (int x = 0; x < ncol; x++) {

                if (key(x, y) !in cell) {
                    app.put("        <td></td>\n");
                } else {
                    Cell c = cell[key(x, y)];

                    if (c) app.put(c.toHtml());
                }
            }
            app.put("    </tr>\n");
        }
        app.put("</table>");

        return app.data;
    }

private:
    void addCell(int x, int y, Cell c) {
        Cell *p = key(x, y) in cell;

        if (x + 1 > ncol) ncol = x + 1;
        if (y + 1 > nrow) nrow = y + 1;

        assert(p is null);
        cell[key(x, y)] = c;
    }

    static uint key(uint x, uint y)
    {
        const offset = 1u << 16;
        return y * offset + x;
    }


    Cell[uint] cell;        // map of positions to cells
    int row = -1;           // current row
    int col;                // current column
    int nrow;               // number of rows
    int ncol;               // number of columns
};

void main()
{
    auto tbl = new Table();

    tbl.newRow();
    tbl.add("Total", 1, 9);
    tbl.add("Subtotal A-C", 1, 3);
    tbl.add("detail A");

    tbl.newRow();
    tbl.add("detail B");

    tbl.newRow();
    tbl.add("detail C");

    tbl.newRow();
    tbl.add("Subtotal D-F", 1, 3);
    tbl.add("detail D");

    tbl.newRow();
    tbl.add("detail E");

    tbl.newRow();
    tbl.add("detail F");

    tbl.newRow();
    tbl.add("Subtotal G-I", 1, 3);
    tbl.add("detail G");

    tbl.newRow();
    tbl.add("detail H");

    tbl.newRow();
    tbl.add("detail I");

    writeln(tbl.toHtml());   
}

答案 2 :(得分:0)

这是我的源行的样子,尝试并自己查看。

auto tbl = new Table();

tbl.newRow();
tbl.add("Total", 1, 9);
tbl.add("Subtotal A-C", 1, 3);
tbl.add("detail A");

tbl.newRow();
tbl.add("Subtotal D-F", 1, 3);
tbl.add("detail B");

tbl.newRow();
tbl.add("Subtotal G-I", 1, 3);
tbl.add("detail C");

tbl.newRow();
tbl.add("detail D");

tbl.newRow();
tbl.add("detail E");

tbl.newRow();
tbl.add("detail F");

tbl.newRow();
tbl.add("detail G");

tbl.newRow();
tbl.add("detail H");

tbl.newRow();
tbl.add("detail I");

writeln(tbl.toHtml());