199 lines
5.9 KiB
HTML
199 lines
5.9 KiB
HTML
|
<!-- index.html -->
|
|||
|
<!DOCTYPE html>
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<meta charset="UTF-8">
|
|||
|
<title>Table Update Example</title>
|
|||
|
<!-- 引入 xlsx 库 -->
|
|||
|
<script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
|||
|
</head>
|
|||
|
|
|||
|
<style>
|
|||
|
/* 页面样式 */
|
|||
|
body {
|
|||
|
font-family: Arial, sans-serif;
|
|||
|
margin: 0;
|
|||
|
padding: 0;
|
|||
|
}
|
|||
|
|
|||
|
/* 表格样式 */
|
|||
|
#data-table {
|
|||
|
width: 95%; /* 减少一些边距 */
|
|||
|
border-collapse: collapse;
|
|||
|
border: 1px solid black;
|
|||
|
margin: auto;
|
|||
|
page-break-inside: avoid; /* 防止在表格内部分页 */
|
|||
|
}
|
|||
|
#data-table th,
|
|||
|
#data-table td {
|
|||
|
border: 1px solid black;
|
|||
|
padding: 8px;
|
|||
|
text-align: left;
|
|||
|
}
|
|||
|
#data-table th {
|
|||
|
background-color: #f2f2f2;
|
|||
|
}
|
|||
|
|
|||
|
/* 打印样式 */
|
|||
|
@media print {
|
|||
|
body, #data-table {
|
|||
|
margin: 0;
|
|||
|
}
|
|||
|
#data-table {
|
|||
|
width: 297mm; /* A4 paper width in landscape mode */
|
|||
|
height: auto;
|
|||
|
margin: 0 auto;
|
|||
|
overflow-x: auto; /* 滚动条只在需要时出现 */
|
|||
|
}
|
|||
|
button {
|
|||
|
display: none;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* 打印按钮样式 */
|
|||
|
button {
|
|||
|
display: block;
|
|||
|
margin: 1em auto;
|
|||
|
padding: 10px 20px;
|
|||
|
font-size: 16px;
|
|||
|
cursor: pointer;
|
|||
|
}
|
|||
|
</style>
|
|||
|
<body>
|
|||
|
<button onclick="window.print()">打印数据</button>
|
|||
|
|
|||
|
<!-- 添加一个导出按钮 -->
|
|||
|
<button onclick="exportToExcel()">导出到Excel</button>
|
|||
|
|
|||
|
<select id="scheduleFilter" onchange="filterTable()">
|
|||
|
<option value="">全部</option>
|
|||
|
<option value="是">是</option>
|
|||
|
<option value="否">否</option>
|
|||
|
</select>
|
|||
|
<table id="data-table">
|
|||
|
<thead>
|
|||
|
<tr>
|
|||
|
<th>时间</th><th> 姓名</th> <th> 时段 </th><th> 上线时间 </th><th> 是否排班 </th><th> 工作状态 </th><th> 全天在线时长</th> <th> 全天背单时长 </th><th> 全天完单量 </th><th> 时段内在线时长 </th><th> 时段内背单时长 </th><th>
|
|||
|
|
|||
|
</tr>
|
|||
|
</thead>
|
|||
|
<tbody>
|
|||
|
<!-- 动态生成的数据行 -->
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.js"></script>
|
|||
|
|
|||
|
<script>
|
|||
|
const socket = io();
|
|||
|
let allRows = [];
|
|||
|
|
|||
|
// 监听 'update_table' 事件
|
|||
|
socket.on('update_table', function(data) {
|
|||
|
const tableBody = document.getElementById('data-table').getElementsByTagName('tbody')[0];
|
|||
|
tableBody.innerHTML = ''; // 清空现有行
|
|||
|
|
|||
|
// 获取当前时间
|
|||
|
const now = new Date();
|
|||
|
const timeString = now.toLocaleString();
|
|||
|
|
|||
|
// 保存原始行数据并生成新的行
|
|||
|
allRows = [];
|
|||
|
data['未及格成员'].forEach(function(rowData) {
|
|||
|
const row = tableBody.insertRow();
|
|||
|
allRows.push(row); // 保存行
|
|||
|
|
|||
|
// 添加时间列
|
|||
|
const timeCell = row.insertCell(0); // 插入到第一列
|
|||
|
timeCell.textContent = timeString;
|
|||
|
|
|||
|
// 添加其他数据列
|
|||
|
rowData.forEach(function(cellData) {
|
|||
|
const cell = row.insertCell();
|
|||
|
cell.textContent = cellData;
|
|||
|
});
|
|||
|
});
|
|||
|
|
|||
|
// 存储数据到localStorage
|
|||
|
localStorage.setItem('allRows', JSON.stringify(allRows));
|
|||
|
localStorage.setItem('scheduleFilter', ''); // 默认筛选值
|
|||
|
});
|
|||
|
|
|||
|
// 加载时检查localStorage中的数据
|
|||
|
window.addEventListener('load', () => {
|
|||
|
const storedAllRows = JSON.parse(localStorage.getItem('allRows'));
|
|||
|
const storedScheduleFilter = localStorage.getItem('scheduleFilter');
|
|||
|
|
|||
|
if (storedAllRows && storedAllRows.length > 0) {
|
|||
|
const tableBody = document.getElementById('data-table').getElementsByTagName('tbody')[0];
|
|||
|
tableBody.innerHTML = ''; // 清空现有行
|
|||
|
storedAllRows.forEach(rowData => {
|
|||
|
const row = tableBody.insertRow();
|
|||
|
rowData.forEach(cellData => {
|
|||
|
const cell = row.insertCell();
|
|||
|
cell.textContent = cellData;
|
|||
|
});
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
if (storedScheduleFilter) {
|
|||
|
document.getElementById('scheduleFilter').value = storedScheduleFilter;
|
|||
|
filterTable();
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
// 连接事件
|
|||
|
socket.on('connect', function() {
|
|||
|
console.log('Connected to server');
|
|||
|
});
|
|||
|
|
|||
|
// 筛选表格函数
|
|||
|
function filterTable() {
|
|||
|
const selectElement = document.getElementById('scheduleFilter');
|
|||
|
const selectedValue = selectElement.value;
|
|||
|
allRows.forEach(row => {
|
|||
|
const isScheduledCell = row.cells[4]; // 假定“是否排班”是第5列
|
|||
|
if (selectedValue === '' || isScheduledCell.textContent === selectedValue) {
|
|||
|
row.style.display = '';
|
|||
|
} else {
|
|||
|
row.style.display = 'none';
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
// 导出到Excel的函数
|
|||
|
function exportToExcel() {
|
|||
|
// 获取表格
|
|||
|
var table = document.getElementById('data-table');
|
|||
|
|
|||
|
// 创建工作表
|
|||
|
var ws = XLSX.utils.table_to_sheet(table);
|
|||
|
|
|||
|
// 创建工作簿
|
|||
|
var wb = XLSX.utils.book_new();
|
|||
|
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
|
|||
|
|
|||
|
// 将工作簿输出为二进制格式
|
|||
|
var wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
|
|||
|
|
|||
|
// 将二进制数据转换为Blob对象
|
|||
|
var blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' });
|
|||
|
|
|||
|
// 创建下载链接
|
|||
|
var link = document.createElement('a');
|
|||
|
link.href = URL.createObjectURL(blob);
|
|||
|
link.download = 'exported_data.xlsx';
|
|||
|
link.click();
|
|||
|
}
|
|||
|
|
|||
|
// 辅助函数,用于将二进制字符串转换为ArrayBuffer
|
|||
|
function s2ab(s) {
|
|||
|
var buf = new ArrayBuffer(s.length);
|
|||
|
var view = new Uint8Array(buf);
|
|||
|
for (var i=0; i<s.length; i++) {
|
|||
|
view[i] = s.charCodeAt(i) & 0xFF;
|
|||
|
}
|
|||
|
return buf;
|
|||
|
}
|
|||
|
</script>
|
|||
|
</body>
|
|||
|
</html>
|