Files
Shudao/111.html
T

855 lines
18 KiB
HTML
Raw Normal View History

2026-06-29 15:32:32 +08:00
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>x-data-spreadsheet</title>
<style>
body { margin:0; padding:20px; font-family:Arial,sans-serif; background-color:#f5f5f5; }
.layout { display:flex; gap:20px; align-items:flex-start; }
.main { flex:1 1 auto; min-width:0; }
#xspreadsheet { width:100%; height:calc(100vh - 140px); min-height:600px; box-shadow:0 2px 10px rgba(0,0,0,0.1); background-color:white; }
.toc-sidebar {
flex: 0 0 200px;
position: sticky;
top: 20px;
max-height: calc(100vh - 40px);
overflow-y: auto;
background: #ffffff;
border-radius: 6px;
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
padding: 12px 0;
box-sizing: border-box;
}
.toc-sidebar h3 {
margin: 0 14px 8px 0;
font-size: 12px;
font-weight: 600;
color: #333;
border-bottom: 1px solid #eee;
padding: 0 14px 8px;
letter-spacing: 0.5px;
text-transform: uppercase;
}
.toc-sheet-group { margin-bottom: 10px; }
.toc-sheet-name {
font-size: 11px;
color: #999;
margin: 4px 14px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.toc-list { list-style: none; padding: 0; margin: 0; }
.toc-list li { margin: 0; }
.toc-link {
display: block;
padding: 5px 14px;
color: #555;
text-decoration: none;
font-size: 12.5px;
line-height: 1.5;
cursor: pointer;
border-left: 2px solid transparent;
transition: background 0.12s, color 0.12s, border-color 0.12s;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.toc-link:hover { background: #f0f7ff; color: #1677ff; }
.toc-link.active {
background: #e6f4ff;
color: #1677ff;
border-left-color: #1677ff;
font-weight: 600;
}
.toc-empty { font-size: 12px; color: #999; padding: 8px 14px; }
2026-06-29 15:32:32 +08:00
</style>
<link rel="stylesheet" href="https://unpkg.com/x-data-spreadsheet@1.1.9/dist/xspreadsheet.css">
</head>
<body>
<h1>x-data-spreadsheet</h1>
<div class="layout">
<div class="main">
<div id="xspreadsheet"></div>
</div>
<aside class="toc-sidebar">
<h3>目录</h3>
<div id="toc-container"></div>
</aside>
</div>
2026-06-29 15:32:32 +08:00
<script src="https://unpkg.com/x-data-spreadsheet@1.1.9/dist/xspreadsheet.js"></script>
<script>
const rawData = {
2026-06-29 15:32:32 +08:00
"name": "Table_0",
"rows": {
"0": {
"cells": {
"19": {
"text": "PD4.2.2",
"merge": [
0,
2
]
}
}
},
"1": {
"cells": {
"0": {
"text": "基本要求",
"merge": [
0,
1
]
},
"2": {
"text": "01.在路基用地和取土坑范国内,己清除地表植被、杂物、积水、淤泥和表土,处理坑塘,并按施工技术规范和设计要求对基底进行压实.表土己充分利用.口2.坝方路基分层坝筑压实,每层表面平整,路拱合适,排水良好,无明显碾压轮迹,无亏坡.口3.己设置施工临时排水系统,避免冲刷边坡,路床顶面无积水.4.在设定取土区内合理取土,无溢开滥挖.完工后己按要求对取土坑和奔土场进行依整.",
"merge": [
0,
19
]
}
}
},
"2": {
"cells": {
"1": {
"text": "项次",
"merge": [
1,
0
]
},
"2": {
"text": "检查项目",
"merge": [
1,
3
]
},
"6": {
"text": "规定值或允许偏差",
"merge": [
0,
2
]
},
"9": {
"text": "实测值或实测差值",
"merge": [
0,
9
]
},
"19": {
"text": "质量评定",
"merge": [
0,
2
]
}
}
},
"3": {
"cells": {
"6": {
"text": "商速公路一级公路"
},
"7": {
"text": "二级公路"
},
"8": {
"text": "三、四级公路"
},
"9": {
"text": "1"
},
"10": {
"text": "2"
},
"11": {
"text": "3"
},
"12": {
"text": "4"
},
"13": {
"text": "5"
},
"14": {
"text": "6"
},
"15": {
"text": "7"
},
"16": {
"text": "8"
},
"17": {
"text": "9"
},
"18": {
"text": "10"
},
"19": {
"text": "平均值、代表值"
},
"20": {
"text": "合格率(%)"
},
"21": {
"text": "合格判定"
}
}
},
"4": {
"cells": {
"1": {
"text": "1A",
"merge": [
6,
0
]
},
"2": {
"text": "医卖医卖",
"merge": [
6,
0
]
},
"3": {
"text": "上路床",
"merge": [
0,
1
]
},
"5": {
"text": "0~0.3m"
},
"6": {
"text": "≥96"
},
"7": {
"text": "≥95"
},
"8": {
"text": "≥94"
}
}
},
"5": {
"cells": {
"3": {
"text": "下路床",
"merge": [
1,
0
]
},
"4": {
"text": "经、中及交通荷载等级"
},
"5": {
"text": "0.3m~0.8m"
},
"6": {
"text": "96"
},
"7": {
"text": "≥95"
},
"8": {
"text": "≥94"
},
"9": {
"merge": [
0,
9
]
}
}
},
"6": {
"cells": {
"4": {
"text": "特重、极重交通荷载等级"
},
"5": {
"text": "0.3m~1.2m"
},
"6": {
"text": "296"
},
"7": {
"text": "≥95"
},
"8": {
"text": "-"
}
}
},
"7": {
"cells": {
"3": {
"text": "上路提",
"merge": [
1,
0
]
},
"4": {
"text": "轻、中及重交通荷载等级"
},
"5": {
"text": "0.8m~1.5m"
},
"6": {
"text": "≥94"
},
"7": {
"text": "≥94"
},
"8": {
"text": "≥93"
}
}
},
"8": {
"cells": {
"4": {
"text": "特薰、极薰交通荷载等级"
},
"5": {
"text": "1.2m~1.9m"
},
"6": {
"text": "≥94"
},
"7": {
"text": "≥94"
},
"8": {
"text": "-"
}
}
},
"9": {
"cells": {
"3": {
"text": "下路提",
"merge": [
1,
0
]
},
"4": {
"text": "轻、中及交通荷载等级"
},
"5": {
"text": "≥1.5m"
},
"6": {
"text": "≥93",
"merge": [
1,
0
]
},
"7": {
"text": "≥92",
"merge": [
1,
0
]
},
"8": {
"text": "≥90",
"merge": [
1,
0
]
}
}
},
"10": {
"cells": {
"4": {
"text": "特、极薰交通荷载等级"
},
"5": {
"text": "≥1.9m"
}
}
},
"11": {
"cells": {
"1": {
"text": "2A"
},
"2": {
"text": "弯沉(0.01mm)",
"merge": [
0,
3
]
},
"6": {
"text": "≤设计验收弯沉值",
"merge": [
0,
2
]
},
"9": {
"merge": [
0,
9
]
}
}
},
"12": {
"cells": {
"1": {
"text": "3"
},
"2": {
"text": "纵断商程(mm)",
"merge": [
0,
3
]
},
"6": {
"text": "+10-15"
},
"7": {
"text": "+10.-20",
"merge": [
0,
1
]
}
}
},
"13": {
"cells": {
"1": {
"text": "4"
},
"2": {
"text": "中线偏位(mm)",
"merge": [
0,
3
]
},
"6": {
"text": "50"
},
"7": {
"text": "100",
"merge": [
0,
1
]
}
}
},
"14": {
"cells": {
"1": {
"text": "5"
},
"2": {
"text": "宽度(mm)",
"merge": [
0,
3
]
},
"6": {
"text": "满足设计要求",
"merge": [
0,
2
]
}
}
},
"15": {
"cells": {
"1": {
"text": "6"
},
"2": {
"text": "平整度(mm)",
"merge": [
0,
3
]
},
"6": {
"text": "415"
},
"7": {
"text": "520",
"merge": [
0,
1
]
}
}
},
"16": {
"cells": {
"1": {
"text": "7"
},
"2": {
"text": "横坡(%)",
"merge": [
0,
3
]
},
"6": {
"text": "±0.3"
},
"7": {
"text": "±0.5",
"merge": [
0,
1
]
}
}
},
"17": {
"cells": {
"1": {
"text": "8"
},
"2": {
"text": "边坡",
"merge": [
0,
3
]
},
"6": {
"text": "满足设计要求",
"merge": [
0,
2
]
}
}
},
"18": {
"cells": {
"0": {
"text": "外观质量",
"merge": [
0,
5
]
},
"6": {
"text": "01.路基边线与边坡未出现单向累计长度超过50m的弯折.口2.路基边坡、护坡道、碎离台无滑坡、爆方或深度超过100mm的冲沟.",
"merge": [
0,
8
]
},
"15": {
"text": "质量保证资料",
"merge": [
0,
3
]
}
}
},
"19": {
"cells": {
"0": {
"text": "工程质量等级评定",
"merge": [
0,
5
]
},
"6": {
"text": "口合格口不合格",
"merge": [
0,
13
]
}
}
},
"len": 20
},
"merges": [
"P19:S19",
"C17:F17",
"G19:O19",
"B3:B4",
"J12:S12",
"G18:I18",
"G3:I3",
"J3:S3",
"G10:G11",
"G15:I15",
"C13:F13",
"B5:B11",
"C18:F18",
"T1:V1",
"C15:F15",
"A20:F20",
"C14:F14",
"H17:I17",
"A2:B2",
"H16:I16",
"A19:F19",
"D8:D9",
"C16:F16",
"T3:V3",
"G12:I12",
"C2:V2",
"H13:I13",
"I10:I11",
"J6:S6",
"C5:C11",
"D10:D11",
"C3:F4",
"G20:T20",
"C12:F12",
"D5:E5",
"H14:I14",
"D6:D7",
"H10:H11"
],
"cols": {
"0": {
"width": 120
},
"1": {
"width": 120
},
"2": {
"width": 120
},
"3": {
"width": 120
},
"4": {
"width": 120
},
"5": {
"width": 120
},
"6": {
"width": 120
},
"7": {
"width": 120
},
"8": {
"width": 120
},
"9": {
"width": 120
},
"10": {
"width": 120
},
"11": {
"width": 120
},
"12": {
"width": 120
},
"13": {
"width": 120
},
"14": {
"width": 120
},
"15": {
"width": 120
},
"16": {
"width": 120
},
"17": {
"width": 120
},
"18": {
"width": 120
},
"19": {
"width": 120
},
"20": {
"width": 120
},
"21": {
"width": 120
}
}
};
// Normalize: x_spreadsheet.loadData accepts an array of sheets or a single sheet
const sheets = Array.isArray(rawData) ? rawData : [rawData];
// ---- TOC builder ----
function cellText(row, col) {
if (!row || !row.cells) return null;
const c = row.cells[col];
if (!c) return null;
return (c.text || '').trim() || null;
}
function extractToc(sheet) {
const items = [];
const rows = sheet.rows || {};
const len = rows.len || 0;
const seen = new Set();
for (let i = 0; i < len; i++) {
const r = rows[i];
if (!r || !r.cells) continue;
const c0 = cellText(r, 0);
const c1 = cellText(r, 1);
const c2 = cellText(r, 2);
// 1) Top-level labels in column 0 (基本要求 / 外观质量 / 工程质量等级评定 / ...)
if (c0 && !seen.has('c0:' + c0)) {
items.push({ label: c0, row: i });
seen.add('c0:' + c0);
continue;
}
// 2) Numbered items in column 1 (项次: 1A, 2A, 3, 4, 5, 6, 7, 8, ...)
if (c1 && /^[0-9]+[A-Za-z]?$/.test(c1)) {
const label = c1 + (c2 ? ' ' + c2 : '');
if (!seen.has('c1:' + c1)) {
items.push({ label, row: i });
seen.add('c1:' + c1);
}
continue;
}
}
return items;
}
function renderToc(sheets) {
const container = document.getElementById('toc-container');
container.innerHTML = '';
let hasAny = false;
sheets.forEach((sheet, sheetIdx) => {
const items = extractToc(sheet);
if (!items.length && sheets.length === 1) return;
hasAny = true;
const group = document.createElement('div');
group.className = 'toc-sheet-group';
if (sheets.length > 1) {
const name = document.createElement('div');
name.className = 'toc-sheet-name';
name.textContent = sheet.name || ('Sheet ' + (sheetIdx + 1));
group.appendChild(name);
}
const ul = document.createElement('ul');
ul.className = 'toc-list';
items.forEach(item => {
const li = document.createElement('li');
const a = document.createElement('a');
a.className = 'toc-link';
a.href = 'javascript:void(0)';
a.dataset.sheet = sheetIdx;
a.dataset.row = item.row;
a.title = item.label + ' (row ' + item.row + ')';
a.innerHTML = item.label + '<span class="row-tag" style="color:#bbb;font-size:10.5px;margin-left:4px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;">·' + item.row + '</span>';
a.addEventListener('click', () => scrollToRow(sheetIdx, item.row, a));
li.appendChild(a);
ul.appendChild(li);
});
group.appendChild(ul);
container.appendChild(group);
});
if (!hasAny) {
const empty = document.createElement('div');
empty.className = 'toc-empty';
empty.textContent = '(未识别到目录项)';
container.appendChild(empty);
}
}
// ---- Scroll handling ----
// x-data-spreadsheet renders the grid on a canvas; rows are NOT in the DOM.
// We scroll by setting the vertical scrollbar's scrollTop, which fires
// the library's internal moveFn -> scrolly() -> re-render.
let __ssRef = null; // populated after load
function getSheetData(sheetIdx) {
if (!__ssRef) return null;
// spreadsheet.datas[] holds the pt instances; .data is shorthand for datas[0]
if (Array.isArray(__ssRef.datas) && __ssRef.datas[sheetIdx]) return __ssRef.datas[sheetIdx];
if (sheetIdx === 0 && __ssRef.data) return __ssRef.data;
return null;
}
function scrollToRow(sheetIdx, rowIndex, linkEl) {
if (!__ssRef) return;
// Mark active
document.querySelectorAll('.toc-link.active').forEach(el => el.classList.remove('active'));
if (linkEl) linkEl.classList.add('active');
try {
const liveData = getSheetData(sheetIdx);
if (!liveData || !liveData.rows || typeof liveData.rows.sumHeight !== 'function') {
console.warn('No live sheet data for index', sheetIdx);
return;
}
const y = liveData.rows.sumHeight(0, rowIndex);
const vbar = __ssRef.sheet && __ssRef.sheet.verticalScrollbar;
if (vbar && vbar.el && vbar.el[0]) {
vbar.el[0].scrollTop = y;
}
} catch (e) {
console.warn('scrollToRow failed:', e);
}
}
2026-06-29 15:32:32 +08:00
// ---- Init ----
2026-06-29 15:32:32 +08:00
document.addEventListener('DOMContentLoaded', function () {
if (typeof x_spreadsheet === 'undefined') {
document.body.innerHTML += '<p style="color:red;margin-top:10px;">Error: x-spreadsheet library failed to load. Check internet connection.</p>';
return;
}
try {
const spreadsheet = x_spreadsheet('#xspreadsheet');
spreadsheet.loadData(sheets);
__ssRef = spreadsheet;
renderToc(sheets);
2026-06-29 15:32:32 +08:00
} catch (e) {
console.error('Error:', e);
document.body.innerHTML += '<p style="color:red;margin-top:10px;">Error: ' + e.message + '</p>';
}
});
</script>
</body>
</html>