在處理網頁中的表格導出Excel時,表格的多表頭需要具體的位置。而網頁中的多表頭,都是采用 colspan 和 rowspan 表示。headRows 采用二維數組表示多表頭。
思路
- 根據屬性
colspan
得到單元格相對於當前行的相對位置 X ,后一行的位置等於prevRow.X +prevRow.colspan
- 根據屬性
rowspan
計算跨行導致,糾正某些單元格被覆蓋的情況,既 X 相等的單元格 ,需要向后移動當前單元格的colspan
個單位。
原始表格
A(0,0) | B(3,0) | C(4,0) | D(6,0) | |||
E | F | G | ||||
H | I | J | K | L |
(0,0)A | (1,0) | (2,0) | (3,0)B | (4,0)C | (5,0) | (6,0)D |
(0,1)E | (1,1) | (2,1)F | (3,1)G | (4,1) | (5,1) | (6,1) |
(0,2)H | (1,2)I | (2,2)J | (3,2)K | (4,2)L | (5,2) | (6,2) |
造成位置提前的原因,主要就是rowspan
,跨列導致。
- 第二行 G 的位置提前,受第一行 B C存在行合並
- 第三行 J K L 位置提前,受到 第一行 B 第二行 F 存在行合並
由此可知行合並影響的的行,受 rowspan
的跨度確定,即需要移動的單元個需滿足兩個條件
- 移動單元格 存在
rowspan
單元格的后邊cur.pos.x>=nextcur.pos.x
- 移動單元格 兩個單元格的Y之差,小於合並行的跨度,
nextcur.pos.y-cur.pos.y<cur.rowspan
根據rowspan
計算正確的 X
知道計算邏輯后,還有一個需要注意的地方,行遍歷需要從最后一行開始遍歷。因為在第一行 B 這一列這種情況。
- B 在第一次計算后,在當前行的位置X=3
- 與之后邊的行中X=3的列分別是第二列的 G 和第三列的 K,而我們想要與之對應的 J
這主要是因為,在第二行的F 列存在行合並,導致 J 的位置提前了。所以,如果從正向開始遍歷,J這列的位置 X 始終少了一個單位。
// author:Herbert
// QQ:464884492
function (headRows) {
var findFieldRows = void 0;
//計算同一行x的位置
headRows.forEach(function (rowCols, y) {
var nextPosx = 0;
rowCols.forEach(function (col, x) {
col.pos = {};
col.pos.x = nextPosx;
col.pos.y = y;
col.colspan = col.colspan || 1;
nextPosx = nextPosx + col.colspan;
});
});
//計算 rowspan對后邊行的影響
for (var rowIndex = headRows.length - 1; rowIndex >= 0; rowIndex--) {
var curRow = headRows[rowIndex];
for (var cellIndex = 0; cellIndex < curRow.length; cellIndex++) {
var curCell = curRow[cellIndex];
console.log("正在處理的行:=》", curCell);
curCell.rowspan = curCell.rowspan || 1;
if (curCell.rowspan > 1) {
//將后邊行中所有與當前cell相同位置的單元格依次后移當前單元格x相等的單元格后移當前單元格clospan個單位
//當前行影響以后(被rowspan包含)所有的行
for (var nextRowindex = rowIndex + 1; nextRowindex < headRows.length && curCell.rowspan > nextRowindex - rowIndex; nextRowindex++) {
//判斷是否存在合並信息
var nextRow = headRows[nextRowindex];
for (var nextCellIndex = 0; nextCellIndex < nextRow.length; nextCellIndex++) {
var nextCell = nextRow[nextCellIndex];
if (nextCell.pos.x >= curCell.pos.x) {
nextCell.pos.x += curCell.colspan;
console.log("需要移動的列:=》", nextCell);
}
}
}
}
}
}
}
測試結果:
- rowspan 移動過程
正在處理的行:=》 { title: 'H', pos: { x: 0, y: 2 }, colspan: 1 }
正在處理的行:=》 { title: 'I', pos: { x: 1, y: 2 }, colspan: 1 }
正在處理的行:=》 { title: 'J', pos: { x: 2, y: 2 }, colspan: 1 }
正在處理的行:=》 { title: 'K', pos: { x: 3, y: 2 }, colspan: 1 }
正在處理的行:=》 { title: 'L', pos: { x: 4, y: 2 }, colspan: 1 }
正在處理的行:=》 { title: 'E', colspan: 2, pos: { x: 0, y: 1 } }
正在處理的行:=》 { title: 'F', rowspan: 2, pos: { x: 2, y: 1 }, colspan: 1 }
需要移動的列:=》 { title: 'J', pos: { x: 3, y: 2 }, colspan: 1, rowspan: 1 }
需要移動的列:=》 { title: 'K', pos: { x: 4, y: 2 }, colspan: 1, rowspan: 1 }
需要移動的列:=》 { title: 'L', pos: { x: 5, y: 2 }, colspan: 1, rowspan: 1 }
正在處理的行:=》 { title: 'G', pos: { x: 3, y: 1 }, colspan: 1 }
正在處理的行:=》 { title: 'A', colspan: 3, pos: { x: 0, y: 0 } }
正在處理的行:=》 { title: 'B', rowspan: 3, pos: { x: 3, y: 0 }, colspan: 1 }
需要移動的列:=》 { title: 'G', pos: { x: 4, y: 1 }, colspan: 1, rowspan: 1 }
需要移動的列:=》 { title: 'J', pos: { x: 4, y: 2 }, colspan: 1, rowspan: 1 }
需要移動的列:=》 { title: 'K', pos: { x: 5, y: 2 }, colspan: 1, rowspan: 1 }
需要移動的列:=》 { title: 'L', pos: { x: 6, y: 2 }, colspan: 1, rowspan: 1 }
正在處理的行:=》 { title: 'C', rowspan: 2, colspan: 2, pos: { x: 4, y: 0 } }
需要移動的列:=》 { title: 'G', pos: { x: 6, y: 1 }, colspan: 1, rowspan: 1 }
正在處理的行:=》 { title: 'D', pos: { x: 6, y: 0 }, colspan: 1 } - 移動完成后效果
當前列: {"title":"A","colspan":3,"pos":{"x":0,"y":0},"rowspan":1}
當前列: {"title":"B","rowspan":3,"pos":{"x":3,"y":0},"colspan":1}
當前列: {"title":"C","rowspan":2,"colspan":2,"pos":{"x":4,"y":0}}
當前列: {"title":"D","pos":{"x":6,"y":0},"colspan":1,"rowspan":1}
當前列: {"title":"E","colspan":2,"pos":{"x":0,"y":1},"rowspan":1}
當前列: {"title":"F","rowspan":2,"pos":{"x":2,"y":1},"colspan":1}
當前列: {"title":"G","pos":{"x":6,"y":1},"colspan":1,"rowspan":1}
當前列: {"title":"H","pos":{"x":0,"y":2},"colspan":1,"rowspan":1}
當前列: {"title":"I","pos":{"x":1,"y":2},"colspan":1,"rowspan":1}
當前列: {"title":"J","pos":{"x":4,"y":2},"colspan":1,"rowspan":1}
當前列: {"title":"K","pos":{"x":5,"y":2},"colspan":1,"rowspan":1}
當前列: {"title":"L","pos":{"x":6,"y":2},"colspan":1,"rowspan":1}