在工做中遇到過這樣的的需求,要用java生成一個以下樣式的html表格,這個樣例只是一個簡單的舉例子,還可能更復雜。最後選擇velocity模版引擎實現,表格最後是什麼樣子,只有得到數據以後才能肯定,因此在代碼中動態建立表格。
html
一、在html中,表格的標籤是<table>
,行的標籤是<tr>
,列的標籤是<td>
。從這些標籤,能夠看出,表格->行->列->單元格,是對錶格的細粒度的控制。
二、在標籤<td>
中,有rowspan和colspan兩個屬性,分別控制着單元格向右和向下佔據幾個單元格,對於默認值、0和1,效果都是同樣的,都只是佔據本身的單元格,不會佔據其餘的單元格。複雜表格的建立,主要就是細粒度的控制這個2屬性。
三、就像在(1)裏面介紹的,爲了細粒度的控制,html抽象出了表格,行,列的標籤。基於java,咱們也能夠抽象出類Table表示表格,抽象出類Cell表示單元格。在類Table中用一個二維數據容納類Cell,這樣就能夠完整的表示一個表格了。
四、類Cell中有四個基本的字段java
private String message = ""; private int rowspan = 0; private int colspan = 0; private boolean visiable = true; public Cell(String message, int rowspan, int colspan, boolean visiable) { this.message = message; this.rowspan = rowspan; this.colspan = colspan; this.visiable = visiable; }
message字段表示要顯示的文本.
rowspan字段表示<td>
標籤中rowspan屬性.
colspan字段表示<td>
標籤中colspan屬性.
visiable字段表示是否顯示<td>
標籤
四、類Table中有三個基本的字段apache
// 建立表格的行數 private int rows = 0; // 建立表格的列數 private int cols = 0; // 二維數組 private Cell[][] cells = null; public Table(int rows, int cols) { this.rows = rows; this.cols = cols; this.cells = new Cell[rows][cols]; init(rows, cols); } private void init(int rows, int cols) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { cells[i][j] = new Cell("A", 1, 1, true); } } }
在建立Table類的時候要傳行數rows、列數cols,用來初始化表格。數組
public void addCell(Cell cell, int row, int col) { int rowIndex = row - 1; int colIndex = col - 1; int rowSize = rowIndex + cell.getRowspan(); int colSize = colIndex + cell.getColspan(); for (int i = rowIndex; i < rowSize; i++) { for (int j = colIndex; j < colSize; j++) { cells[i][j].setVisiable(false); cells[i][j].setMessage("noVisiable"); } } cells[rowIndex][colIndex] = cell; }
這個addCell方法是類Table的核心方法,處理添加的Cell。row和col參數(都從1開始),指定了Cell的起始位置。處理的邏輯:從Cell的起始位置開始,按照rowspan和colspan的值,分別向右和向下的Cell的visiable屬性設置爲false(不顯示),那麼在velocity渲染的時候就不會顯示這些單元格。添加的Cell就能佔據這些不會顯示的單元格的位置。測試
一、Table類this
public class Table { // 建立表格的行數 private int rows = 0; // 建立表格的列數 private int cols = 0; // 二維數組 private Cell[][] cells = null; public Table(int rows, int cols) { this.rows = rows; this.cols = cols; this.cells = new Cell[rows][cols]; init(rows, cols); } private void init(int rows, int cols) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { cells[i][j] = new Cell("A", 1, 1, true); } } } public void addCell(Cell cell, int row, int col) { int rowIndex = row - 1; int colIndex = col - 1; int rowSize = rowIndex + cell.getRowspan(); int colSize = colIndex + cell.getColspan(); for (int i = rowIndex; i < rowSize; i++) { for (int j = colIndex; j < colSize; j++) { cells[i][j].setVisiable(false); cells[i][j].setMessage("noVisiable"); } } cells[rowIndex][colIndex] = cell; } public int getRows() { return rows; } public void setRows(int rows) { this.rows = rows; } public int getCols() { return cols; } public void setCols(int cols) { this.cols = cols; } public Cell getCell(int row, int col) { return cells[row - 1][col - 1]; } public void setCells(Cell[][] cells) { this.cells = cells; } }
二、Cell類spa
public class Cell { private String message = ""; private int rowspan = 0; private int colspan = 0; private boolean visiable = true; public Cell(String message, int rowspan, int colspan, boolean visiable) { this.message = message; this.rowspan = rowspan; this.colspan = colspan; this.visiable = visiable; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public int getRowspan() { return rowspan; } public void setRowspan(int rowspan) { this.rowspan = rowspan; } public int getColspan() { return colspan; } public void setColspan(int colspan) { this.colspan = colspan; } public boolean isVisiable() { return visiable; } public void setVisiable(boolean visiable) { this.visiable = visiable; } }
三、velocitycode
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>table</title> </head> <body> <table border="1"> #foreach($row in [1..$table.rows]) <tr> #foreach($col in [1..$table.cols]) #set ($cell = $table.getCell($row, $col)) #if($cell.visiable) <td rowspan="$cell.rowspan" colspan="$cell.colspan" align="center">$cell.message</td> #end #end </tr> #end </table> </body> </html>
四、測試類htm
public static void main(String[] args) { Table table = new Table(4, 7); table.addCell(new Cell("sample", 2, 2, true), 2, 2); VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); ve.init(); Template t = ve.getTemplate("example.vm"); VelocityContext ctx = new VelocityContext(); ctx.put("table", table); StringWriter sw = new StringWriter(); t.merge(ctx, sw); System.out.println(sw.toString()); }
五、簡單的效果圖
blog
這裏只是簡單的介紹了一種實現複雜表格的思路,舉例子中用的java和velocity,其實不限於這2者,單元格的屬性也能夠擴展。還能夠看其餘的文章:
http://www.easyjf.com/blog/html/20080109/1015823.html
https://www.javaworld.com/article/2077810/open-source-tools/complex-html-tables-made-easy-with-apache-velocity.html