可持久化存储表格信息和样式

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><!-- bootstrap图标库 --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.2/font/bootstrap-icons.css"><title>Excel表格</title><style>* {margin: 0;padding: 0;}body {user-select: none;}.container {position: relative;}.operateBox {width: 100vw;height: 145px;position: fixed;z-index: 999;top: 0px;left: 0;background-color: #fff;border-bottom: 1px solid rgb(95, 95, 95);}.handle {position: absolute;z-index: 999;top: 10px;left: 1vw;width: 97vw;height: 90px;border: 2px solid rgb(31, 117, 255);background-color: #fff;overflow: auto;}.handle div {position: relative;}.handle button,.handle select,.handle input {position: absolute;top: var(--top, 2px);left: var(--left, 2px);font-size: 17px;}.handle select {width: 128px;height: 24px;font-size: 15px;}.handle input {width: 59px;height: 20px;font-size: 13px;}button,select {cursor: pointer;}.handle .color input {display: none;}.minBtn {width: 30px;height: 25px;background-color: white;border: 1px solid rgb(153, 152, 152);}.minBtn:hover {/* border: 1px solid black; */background-color: rgb(235, 235, 235);}.contentBox {position: absolute;z-index: 999;top: 110px;left: 1vw;width: 96vw;height: 30px;border: 2px solid rgb(31, 117, 255);line-height: 30px;padding-left: 1vw;background-color: #fff;overflow: hidden;}.contentBox .content {user-select: text;}.contentBox .content::selection,.mainTable tr td span::selection {background: #2cb5a8;color: #ffffff;}.contentBox .coordinate {margin-right: 20px;padding-right: 20px;border-right: 1px solid black;font-weight: 800;}.mainTable {width: 97vw;position: absolute;top: 150px;left: 1vw;display: inline-block;}.mainTable tr td {width: 150px;height: 50px;background-color: white;border: 1px solid rgb(12, 126, 255);box-sizing: border-box;text-align: center;}.mainTable tr td.click {border: 3px solid rgb(0, 82, 247) !important;}.mainTable tr td input {width: 98%;height: 100%;border: none;padding-left: 2%;font-size: 15px;user-select: text;text-align: center;}.mainTable tr td input:focus {outline: none;}.mainTable tr:first-child td {border-top-width: 2px;font-weight: 900;font-size: 17px;}.mainTable tr td:first-child {border-left-width: 2px;font-weight: 900;font-size: 17px;}.mainTable tr:first-child td.active,.mainTable tr td:first-child.active {background-color: rgb(174, 217, 255);}.mainTable tr td:last-child {border-right-width: 2px;}.mainTable tr:last-child td {border-bottom-width: 2px;}.rightClick {width: 160px;height: 210px;background-color: rgba(255, 255, 255, 0.9);border: 2px solid rgb(0, 149, 255);position: fixed;z-index: 99;display: none;}.rightClick button {width: 110px;height: 30px;color: white;border: none;position: absolute;left: 25px;top: var(--top);}.red {background-color: rgb(255, 0, 0);}.blue {background-color: rgb(0, 128, 255);}.multipleChoice {position: absolute;display: none;opacity: 0;}.addRow,.addCol,.reduceRow,.reduceCol {position: fixed;width: 20px;height: 20px;color: white;border: none;background-color: rgb(0, 123, 255);border-radius: 3px;font-size: 20px;opacity: 0.9;}.reduceRow,.reduceCol {background-color: rgb(248, 69, 41);}.addRow {left: 3px;bottom: 0;}.addCol {top: 147px;right: 0;}.reduceRow {left: 3px;bottom: 22px;}.reduceCol {top: 147px;right: 22px;}</style>
</head><body><div class="container"><div class="operateBox"><div class="handle"><div class="color"><input type="color" class="textColor" oninput="textStyle('color', this.value)"><button class="minBtn" style="--top: 30px;" title="文字颜色">A</button></div><div class="color"><input type="color" class="BGColor" oninput="textStyle('background-color', this.value)"><button class="minBtn" style="--top: 30px; left: 35px;" title="背景颜色"><i class="bi bi-paint-bucket"></i></button></div><div class="color"><input type="color" class="tableColor" oninput="textStyle('border-color', this.value)"><button class="minBtn" style="--top: 30px; left: 67px;" title="表格线颜色"><i class="bi bi-grid-3x3"></i></button></div><div><button style="--left: 100px; --top: 30px;" class="minBtn" onclick="textStyle('text-align','left')" title="左对齐"><i class="bi bi-text-left"></i></button><button style="--left: 134px; --top: 30px;" class="minBtn" onclick="textStyle('text-align','center')" title="水平居中"><i class="bi bi-text-center"></i></button><button style="--left: 167px; --top: 30px;" class="minBtn" onclick="textStyle('text-align','right')" title="右对齐"><i class="bi bi-text-right"></i></button><button style="font-size: 20px; --top: 60px;" class="minBtn" onclick="textStyle('font-weight', 700)" title="加粗"><i class="bi bi-type-bold"></i></button><button style="--left: 35px; --top: 60px;" class="minBtn" onclick="textStyle('font-style', 'italic')" title="倾斜"><i class="bi bi-type-italic"></i></button><button style="--left: 67px; --top: 60px;" class="minBtn" onclick="textStyle('text-decoration', 'underline')" title="下划线"><i class="bi bi-type-underline"></i></button><button style="--left: 100px; --top: 60px;" class="minBtn" onclick="textStyle('vertical-align', 'bottom')" title="底端对齐"><i class="bi bi-align-bottom"></i></button><button style="--left: 134px; --top: 60px;" class="minBtn" onclick="textStyle('vertical-align', 'middle')" title="垂直居中"><i class="bi bi-align-middle"></i></button><button style="--left: 167px; --top: 60px;" class="minBtn" onclick="textStyle('vertical-align', 'top')" title="顶端对齐"><i class="bi bi-align-top"></i></button><select class="selectFontFamily"><option value="Microsoft YaHei">微软雅黑</option><option value="SimHei">黑体</option><option value="SimSun">宋体</option><option value="NSimSun">新宋体</option><option value="FangSong">仿宋</option><option value="KaiTi">楷体</option><option value="LiSu">隶书</option><option value="YouYuan">幼圆</option><option value="STXihei">华文细黑</option><option value="STHeiti">华文黑体</option><option value="STKaiti">华文楷体</option><option value="STSong">华文宋体</option><option value="STFangsong">华文仿宋</option><option value="FZShuTi">方正舒体</option><option value="FZYaoti">方正姚体</option><option value="STCaiyun">华文彩云</option><option value="STHupo">华文琥珀</option><option value="STLiti">华文隶书</option><option value="STXingkai">华文行楷</option><option value="STXinwei">华文新魏</option></select><input type="number" style="--left: 134px;" placeholder="字号" oninput="textStyle('font-size', this.value + 'px')" value="16"></div></div><div class="contentBox"><span class="coordinate"></span><span class="content"></span></div></div><table class="mainTable" border="0" cellspacing="0" cellpadding="0"></table></div><div class="rightClick"><button class="removeText red" style="--top: 10px;">清除文字</button><button class="reductionStyle blue" style="--top: 50px;">还原默认样式</button><button class="checkDuplicates blue" style="--top: 90px;">检查重复项</button><button class="selectSame blue" style="--top: 130px;">选择相同内容</button><button class="reverseSelect blue" style="--top: 170px;">反向选择</button></div><div class="multipleChoice"></div><button class="addRow" onclick="addOrReduceTd(1, 0)" title="增加一行">+</button><button class="addCol" onclick="addOrReduceTd(0, 1)" title="增加一列">+</button><button class="reduceRow" onclick="addOrReduceTd(1, 2)" title="减少一行">-</button><button class="reduceCol" onclick="addOrReduceTd(2, 1)" title="减少一列">-</button><script>//#regionconst mainTable = document.querySelector('.mainTable');const handle = document.querySelector('.handle');const contentBox = document.querySelector('.contentBox');const coordinate = document.querySelector('.coordinate');const content = contentBox.querySelector('.content');const rightClick = document.querySelector('.rightClick');const rightClickBtn = document.querySelectorAll('.rightClick button');const removeText = rightClick.querySelector('.removeText');const textColor = document.querySelector('.textColor');const BGColor = document.querySelector('.BGColor');const tableColor = document.querySelector('.tableColor');const multipleChoice = document.querySelector('.multipleChoice');const reductionStyle = rightClick.querySelector('.reductionStyle');const selectFontFamily = document.querySelector('.selectFontFamily');const selectFontFamilyOption = document.querySelectorAll('.selectFontFamily option');const checkDuplicates = rightClick.querySelector('.checkDuplicates');const selectSame = rightClick.querySelector('.selectSame');const reverseSelect = rightClick.querySelector('.reverseSelect');// 全部td、所有第一列的td、所有第一行的td、所有可以点击的td(可以操作的td)let allTd, allFirstColTd, allFirstRowTd, allowClickTd;let currentMultipleTd = [];// 大写字母let letterList = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');// 是否允许多选let multipleFlag = true;let startY, startX;let multipleContent = [];// 第一个td、最后一个tdlet firstTd, lastTd;// 行数、列数let rows, cells;// ctrl+c 复制的内容和样式let ctrlC = {text: '',style: ''};//#endregion// 增加或减少一行、一列     ( 0表示添加一行或一列、1表示不变、2表示减少一行或一列 )function addOrReduceTd(cellNum, rowNum) {rows = mainTable.rows.length;cells = mainTable.rows.item(0).cells.length;if(cells - cellNum > letterList.length) return;createdTable(cells - cellNum, rows - rowNum);renderTable();localStorage.setItem('make_table_rows', rows - rowNum);localStorage.setItem('make_table_cells', cells - cellNum);// 滚动到指定位置,先判断是增加还是减少,cellNum + rowNum 大于 2 表示减少(cellNum + rowNum > 2 ? cellNum < rowNum : cellNum > rowNum) ? window.scroll(0, window.innerHeight) : window.scroll(document.documentElement.scrollWidth, 0);}// 两个元素是否相交function isIntersect(element1, element2) {var rect1 = element1.getBoundingClientRect();var rect2 = element2.getBoundingClientRect();return !(rect1.right < rect2.left || rect1.left > rect2.right || rect1.bottom < rect2.top || rect1.top > rect2.bottom);}// 选择多个tdfunction selectMultipleTd(multipleTd) {multipleContent = [];// 如果被选中td有内容,则添加到multipleContent数组multipleTd.forEach(item2 => item2.querySelector('span').innerText && multipleContent.push(item2.querySelector('span').innerText));content.innerText = multipleContent.join('、');// 第一个和最后一个tdfirstTd = multipleTd[0];lastTd = multipleTd[multipleTd.length - 1];// 为不能选中的td添加classallFirstRowTd.forEach((item2, index) => {item2.classList.remove('active');multipleTd.forEach(item3 => index == item3.getAttribute('data-col') && item2.classList.add('active'));});allFirstColTd.forEach((item2, index) => {item2.classList.remove('active');multipleTd.forEach(item3 => index == item3.getAttribute('data-row') && item2.classList.add('active'));});// 显示坐标~坐标coordinate.innerText = firstTd && firstTd.getAttribute('data-letter') + firstTd.getAttribute('data-row') + '~' + lastTd.getAttribute('data-letter') + lastTd.getAttribute('data-row');}mainTable.addEventListener('mousedown', e => {multipleFlag = false;startY = e.pageY;startX = e.pageX;multipleChoice.style.display = 'block';});// 多选tdmainTable.addEventListener('mousemove', e => {if (multipleFlag) return;if (e.pageX > startX && e.pageY > startY) { //右下multipleChoice.style.inset = `${startY}px auto auto ${startX}px`;multipleChoice.style.width = e.pageX - startX + 'px';multipleChoice.style.height = e.pageY - startY + 'px';} else if (e.pageX < startX && e.pageY > startY) { //左下multipleChoice.style.inset = `${startY}px ${window.innerWidth - startX - 20}px auto auto`;multipleChoice.style.width = startX - e.pageX + 'px';multipleChoice.style.height = e.pageY - startY + 'px';} else if (e.pageX < startX && e.pageY < startY) { //左上multipleChoice.style.inset = `auto ${window.innerWidth - startX - 20}px ${window.innerHeight - startY -20}px auto`;multipleChoice.style.width = startX - e.pageX + 'px';multipleChoice.style.height = startY - e.pageY + 'px';} else if (e.pageX > startX && e.pageY < startY) { //右上multipleChoice.style.inset = `auto auto ${window.innerHeight - startY -20}px ${startX}px`;multipleChoice.style.width = e.pageX - startX + 'px';multipleChoice.style.height = startY - e.pageY + 'px';}// 选中所有与multipleChoice相交的tdallowClickTd.forEach(item => isIntersect(item, multipleChoice) ? item.classList.add('click') : (e.ctrlKey || item.classList.remove('click')));// 重新获取currentMultipleTdcurrentMultipleTd = document.querySelectorAll('td.click');selectMultipleTd(currentMultipleTd);});document.addEventListener('mouseup', () => {multipleFlag = true;multipleChoice.style.width = '0px';multipleChoice.style.height = '0px';multipleChoice.style.display = 'none';});// 设置最小宽度handle.style.minWidth = window.outerWidth - 100 + 'px';contentBox.style.minWidth = window.outerWidth - 100 + 'px';// 创建表格function createdTable(width, height) {let createTd = '';let createTr = '';let col = 0,row = -1;// 设置最小宽度mainTable.style.minWidth = width * 150 + 'px';// 创建tdfor (let i = 0; i < width + 1; i++) {let td = `<td onclick="clickTd(this)" ondblclick="dblclickTd(this)" data-col=${col} data-letter=${letterList[col - 1]}><span></span><input type="text" onblur="inputBlur(this.parentNode)" onkeyup="tdInputEnter()" style="display: none;"></td>`;// 标识这个td是第几列col >= width ? col = 0 : col++;// 序号列if (i <= 0) td = `<td style="width: 50px;"></td>`;createTd += td;}// 创建trfor (let i = 0; i < height + 1; i++) {// 把创建好的td放入trconst tr = '<tr>' + createTd + '</tr>';createTr += tr;}// 把创建好的tr和td放到table里面mainTable.innerHTML = createTr;allTd = document.querySelectorAll('.mainTable tr td');allTd.forEach((item, index) => {// 添加序号行item.setAttribute('data-row', row);index % (width + 1) == 0 && row++;});// 获取第一列allFirstColTd = document.querySelectorAll('.mainTable tr td:first-child');// 如果index等于零,则不添加序号列allFirstColTd.forEach((item, index) => index == 0 ? item.innerHTML = '' : item.innerHTML = index);// 获取第一行allFirstRowTd = document.querySelectorAll('.mainTable tr:first-child td');// 移除第一行所有td的DOM事件allFirstRowTd.forEach((item, index) => {item.removeAttribute('onclick');item.removeAttribute('ondblclick');// 如果index大于零,则不添加序号列if (index > 0) item.innerHTML = letterList[index - 1];});// 获取所有可以点击的tdallowClickTd = document.querySelectorAll('td[onclick]');}// 宽度、长度let tableWidth = parseInt(localStorage.getItem('make_table_cells')) || 12,tableHeight = parseInt(localStorage.getItem('make_table_rows')) || 12;createdTable(tableWidth, tableHeight);// 单击tdfunction clickTd(td) {const startTd = currentMultipleTd[0];let flag = false;// 按住ctrl则不移除之前的,可以多选event.ctrlKey || allowClickTd.forEach(item => item.classList.remove('click'));// 添加边框td.classList.add('click');//显示坐标coordinate.innerText = td.getAttribute('data-letter') + td.getAttribute('data-row');// 按住shift,连续多选if(event.shiftKey) {allowClickTd.forEach(item => {// 开始的td(上次点击的td)if(item == startTd) flag = true;// 添加中间所有tdif(flag) item.classList.add('click');// 结束的td(当前点击的td)if(item == td) flag = false;});}currentMultipleTd = document.querySelectorAll('td.click');selectMultipleTd(currentMultipleTd);}// 双击tdfunction dblclickTd(td) {const span = td.querySelector('span');const input = td.querySelector('input');// 隐藏span,显示输入框input.setAttribute('style', td.getAttribute('style'));input.value = span.innerHTML;input.style.display = 'block';span.style.display = 'none';input.focus();}// td中的输入框失去焦点function inputBlur(td) {const span = td.querySelector('span');const input = td.querySelector('input');// 把输入框的值给spanspan.innerHTML = input.value;// 显示span,隐藏输入框span.style.display = 'block';input.style.display = 'none';td.classList.remove('click');}// 删除内容removeText.addEventListener('click', () => currentMultipleTd.forEach(item => item.querySelector('span').innerHTML = content.innerHTML = ''));// 还原样式reductionStyle.addEventListener('click', () => currentMultipleTd.forEach(item => item.removeAttribute('style')));// 检查重复项checkDuplicates.addEventListener('click', () => {currentMultipleTd.forEach(item1 => {item1.classList.remove('click');currentMultipleTd.forEach(item2 => {// 如果item1不等于item2 并且 内容不为空 则为真if(item1 != item2 && item1.querySelector('span').innerText != '') {// 如果内容相等则添加class类if(item1.querySelector('span').innerText == item2.querySelector('span').innerText) {item1.classList.add('click');item2.classList.add('click');}}});});// 重新获取currentMultipleTdcurrentMultipleTd = document.querySelectorAll('td.click');selectMultipleTd(currentMultipleTd);});// 选择相同内容selectSame.addEventListener('click', () => {const currentTd = currentMultipleTd[0].querySelector('span').innerText;allowClickTd.forEach(item => {item.classList.remove('click');item.querySelector('span').innerText == currentTd && item.classList.add('click');});// 重新获取currentMultipleTdcurrentMultipleTd = document.querySelectorAll('td.click');selectMultipleTd(currentMultipleTd);});// 反选内容reverseSelect.addEventListener('click', () => {// 过滤出两个数组中不重复的tdconst newArr = [...allowClickTd].filter(item => !([...allowClickTd].includes(item) && [...currentMultipleTd].includes(item)));// 移除当前选择td的classcurrentMultipleTd.forEach(item => item.classList.remove('click'));// 添加classnewArr.forEach(item => item.classList.add('click'));// 重新获取currentMultipleTdcurrentMultipleTd = document.querySelectorAll('td.click');selectMultipleTd(currentMultipleTd);});// 鼠标离开菜单或点击按钮,则隐藏右键菜单rightClick.addEventListener('mouseleave', () => rightClick.style.display = 'none');rightClickBtn.forEach(item => item.addEventListener('click', () => rightClick.style.display = 'none'));// 禁用原生右键菜单document.addEventListener('contextmenu', e => e.preventDefault());// 显示右键菜单mainTable.addEventListener('contextmenu', e => {rightClick.style.display = 'block';// 右键菜单的高超出屏幕则减少 tope.clientY > window.innerHeight - rightClick.offsetHeight ? rightClick.style.top = e.clientY - rightClick.offsetHeight + 10 + 'px' : rightClick.style.top = e.clientY - 10 + 'px';// 右键菜单的宽超出屏幕则减少 lefte.clientX > window.innerWidth - rightClick.offsetWidth ? rightClick.style.left = e.clientX - rightClick.offsetWidth + 10 + 'px' : rightClick.style.left = e.clientX - 10 + 'px';});// 获取本地储存const persistenceData = JSON.parse(localStorage.getItem('make_table_data')) || [];const persistenceStyle = JSON.parse(localStorage.getItem('make_table_style')) || [];// 渲染出上次关闭页面时的数据和样式function renderTable() {// 按行获取每个td元素let allRowData1 = []for (let i = 0; i < mainTable.rows.length; i++) {if(i <= 0) continue;let rowArr = [];[...mainTable.rows.item(i).cells].forEach((item, index) => {if(index <= 0) return;rowArr.push(item);});allRowData1.push(rowArr);}// 渲染出上次关闭页面时的数据和样式allRowData1.forEach((item1, index1) => {item1.forEach((item2, index2) => {const span = item2.querySelector('span');// 如果有数据则渲染if(persistenceData[index1]) if(persistenceData[index1][index2]) span.innerText = persistenceData[index1][index2];if(persistenceStyle[index1]) if(persistenceStyle[index1][index2]) item2.setAttribute('style', persistenceStyle[index1][index2]);});});}renderTable();// 页面关闭之前window.addEventListener('beforeunload', () => {allowClickTd.forEach(item => item.querySelector('input').blur());let finallyArr = [];// 先按行获取每个td元素const allRowData2 = []for (let i = 0; i < mainTable.rows.length; i++) {if(i <= 0) continue;let rowArr = [];[...mainTable.rows.item(i).cells].forEach((item, index) => {if(index <= 0) return;rowArr.push(item);});allRowData2.push(rowArr);}// 每行td的内容allRowData2.forEach(item1 => {let arr = []item1.forEach(item2 => arr.push(item2.innerText));finallyArr.push(arr);});localStorage.setItem('make_table_data', JSON.stringify(finallyArr));// 清空finallyArrfinallyArr = []// 每行td的样式allRowData2.forEach(item1 => {let arr = []item1.forEach(item2 => arr.push(item2.getAttribute('style')));finallyArr.push(arr);});localStorage.setItem('make_table_style', JSON.stringify(finallyArr));});function tdInputEnter() {// 在输入框按回车使其失去焦点if (event.code == 'Enter') event.target.blur();}// 点击颜色表单的父元素,显示其颜色表单textColor.parentElement.addEventListener('click', () => textColor.click());BGColor.parentElement.addEventListener('click', () => BGColor.click());tableColor.parentElement.addEventListener('click', () => tableColor.click());// 文字样式function textStyle(key, val) {currentMultipleTd.forEach(item => {if(key == 'text-align') item.style[`${key}`] = val;else if(key.match('color')) {item.style[`${key}`] = val;event.target.nextElementSibling.style.color = val;}else item.style[`${key}`] == val ? item.style[`${key}`] = 'initial' : item.style[`${key}`] = val;});}// 文字字体样式selectFontFamily.addEventListener('input', () => currentMultipleTd.forEach(item => item.style.fontFamily = selectFontFamily.value));selectFontFamilyOption.forEach(item => item.style.fontFamily = item.value);document.addEventListener('keyup', e => {if (e.key == 'a' && e.ctrlKey) { // 全选内容allowClickTd.forEach(item => item.classList.add('click'));currentMultipleTd = document.querySelectorAll('td.click');selectMultipleTd(currentMultipleTd);} else if (e.key == 'c' && e.ctrlKey) { //复制内容ctrlC.text = currentMultipleTd[0].querySelector('span').innerText;ctrlC.style = currentMultipleTd[0].getAttribute('style');} else if (e.key == 'v' && e.ctrlKey) { //粘贴内容currentMultipleTd.forEach(item => {if(ctrlC.text) item.querySelector('span').innerText = ctrlC.text;if(ctrlC.style) item.setAttribute('style', ctrlC.style);});}});document.addEventListener('keypress', e => {// 查看是否有输入框获取焦点let flag = false;for (let i = 0; i < allowClickTd.length; i++) {if(allowClickTd[i].querySelector('input') == document.activeElement) {flag = true;break;}}// 如果没有焦点,则让其获取焦点if(!flag) dblclickTd(currentMultipleTd[0]);});function selectLine(tdArr, data) {tdArr.forEach(item1 => {item1.addEventListener('click', e => {currentMultipleTd = [];allowClickTd.forEach(item2 => {if(e.target.innerText == item2.getAttribute(`data-${data}`)) {item2.classList.add('click');currentMultipleTd.push(item2);} else item2.classList.remove('click');});selectMultipleTd(currentMultipleTd);});});}// 选择一列selectLine(allFirstRowTd, 'letter');// 选择一行selectLine(allFirstColTd, 'row');</script>
</body></html>

前端仿Excel表格相关推荐

  1. vue3.0 + xlsx 实现纯前端生成excel表格

    vue3.0 + xlsx 实现纯前端生成excel表格 1.安装依赖 npm install xlsx --save 2.导入依赖 import * as XLSX from 'xlsx' // V ...

  2. html5生成excel,H5纯前端生成Excel表格

    H5纯前端生成Excel表格方法如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 var arr = [ 14 { 15 "姓名":"喵喵喵" ...

  3. 使用js-export-excel插件实现前端导出excel表格

    js-export-excel 前端导出excel模板 1.下载 npm install js-export-excel 2.使用 /*** * 前端生成excel 表格(基于 js-export-e ...

  4. html 仿excel,智表-浏览器端仿EXCEL表格jQuery插件

    智表(ZCELL)是一款浏览器端仿EXCEL表格jQuery插件.智表可以为你提供EXCEL般的智能体验,并带有灵活的单元格选中与实时计算功能,强大的复制与粘贴功能,标准化数据加载与获取,以及灵活的外 ...

  5. Qt高仿Excel表格组件-支持冻结列、冻结行、内容自适应和合并单元格

    目录 一.概述 二.效果展示 三.实现思路 1.冻结行.冻结列 2.行高自适应 3.蚂蚁线 四.测试代码 1.添加表格数据 2.设置冻结行.列 3.行高.列宽 4.单元格背景色 5.单元格文字 6.其 ...

  6. VUE纯前端导出excel表格功能《转载》

    插件:使用vue-json-excel插件实现Vue纯前端导出简单的Excel表格功能. 使用方法 1. 安装依赖 npm install vue-json-excel 2. 引入组件 a. 全局引入 ...

  7. 纯前端实现excel表格导入导出

    前言 github: https://github.com/stardew516... 以往做excel表格下载功能的时候,都是后端生成好表格后,存储在某个地方,然后给前端一个链接,前端使用a标签加d ...

  8. 纯前端导入excel表格数据

    安装插件 js-xlsx npm install xlsx --save js-xlsx 使用js-xlsx时,前端可以将后端返回的json数据拼接成自己需要导出的格式,下载到电脑中,完全不依赖后端. ...

  9. vue 前端导出Excel表格(基础版 + 多级标题)纯前端导出

    先看效果 纯前端基础导出的Excel表格 纯前端多级表头导出的Excel表格 基础导出下面赋源代码 1.安装依赖 npm install vue-json-excel 2.在项目的入口 main.js ...

最新文章

  1. python处理文本格式_python linecache 处理固定格式文本数据的方法
  2. Python 基于Python生成短8位唯一id解决方案
  3. Matlab去掉数组中0
  4. C++设计模式-迭代器模式
  5. 容器编排技术 -- 从零开始k8s
  6. java 房贷计算器_求一房贷计算器java源程序
  7. php错误和异常的处理方式
  8. 硬核干货来啦:Js数组去重,赶快收藏吧
  9. python遗传算法解简单整数规划与原理探究
  10. cad文件管理服务器,CAD文件管理(ZT)
  11. elementUi——select选择框的下拉框样式调整——基础积累
  12. Oracle 锁详解(lock)
  13. birt 报表与润乾报表对比
  14. FileZilla FTP服务器源代码分析
  15. vue商城第13 订单确认模块 14订单成功页面
  16. OpenAI击败Dota 2世界冠军后记:如何训练你的AI
  17. java 打印详解_Java格式化输出printf()详解
  18. 八、Pytest自动化测试框架 — Pytest测试报告
  19. 云南初中计算机考试试题,云南省初中学业水平考试信息技术复习+练习题
  20. nextJs 跨域访问接口数据

热门文章

  1. 这不是我心目中的比目猪!快来看看这只3D小猪佩奇!
  2. C++MessageBox简介
  3. O2O的用户画像构建
  4. Linux防火墙关闭
  5. X10SRA以及X10SRA-F主板启动针脚在先马黑洞机箱上的插法
  6. 如何使用支付宝充值美区App store的礼品卡
  7. 在服务器中配置pytorch
  8. apple mac 系统键盘输入乱码
  9. 利用ipv6远程桌面,彻底解决校园网掉线问题
  10. springsocial/oauth2---绑定和解绑处理【QQ绑定异常,微信解绑302/ERR_TOO_MANY_REDIRECTS】