将 WPS 中的表格转换成笔记中的表格(处理合并单元格)

本贴最后更新于 729 天前,其中的信息可能已经事过景迁

简介

主要是为了解决从 Excel 或者 WPS 中复制表格粘贴到笔记中后,因合并单元格没处理好导致表格数据混乱的问题。

之前是用表格挂件的方式来解决,但是感觉使用挂件来放表格数据的话,表格的内容跟笔记内容割裂开了,在全局搜索的时候,表格中命中的内容无法作为搜索结果来呈现。

所以这次换个方式:将从 Excel 或者 WPS 中复制的表格转成笔记支持的表格并插入到笔记中,让表格内容成为笔记正文。

实现思路

image20230322114319c2204b1.png

使用方法

  1. 设置(Alt+P)——外观——代码片段——设置——JS中添加并启用代码片段,启用后,笔记右上角多出一个 表格转换 的图标
  2. 在 WPS 中选中表格并复制,粘贴到 LuckSheet 表格挂件中;
  3. 粘贴到挂件后,表格还是选中状态,此时按Ctrl+C再次复制;
  4. 点击右上角的【表格转换】图标,提示成功后,对应表格模板字符串已经复制到剪切板;
  5. 到笔记中按Ctrl+V粘贴表格。

**注意:**第二步在 WPS 中选中表格时,表头(也就是第一行)不要有行合并(多行合并),这种情况还未进行处理。

如果你的表格第一行就有行合并,可以往上多选一行空单元格作为表头以免出现异常。

视频演示

演示环境:V2.7.2 Windows 10

表格挂件压缩包

表格.zip

备注:挂件中全屏按钮要生效的话,需要到主题的 theme.css 中添加一个样式:

.fullScreen2 { position: fixed; top: 30px; left: 0; width: 100vw !important; height: 95vh !important; z-index: 200; }

代码片段

(() => { // 请求函数 function request(url, data = null, method = "POST") { return new Promise((resolve, reject) => { if (method.toUpperCase() == "POST") { fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }) .then( (data) => resolve(data.json()), (error) => { reject(error); } ) .catch((err) => { console.error("请求失败:", err); }); } }); } // 复制内容到剪切板 function patseIntoClipboard(txt) { let status = false; const input = document.createElement("textarea"); document.body.appendChild(input); input.innerHTML = txt; input.select(); if (document.execCommand("copy")) { document.execCommand("copy"); status = true; showMessage("表格内容已复制到剪切板"); } else { showMessage("复制失败"); } document.body.removeChild(input); return status; } // 弹出提示信息 async function showMessage(msg, timeout = 2000) { await request("/api/notification/pushMsg", { msg, timeout }); } // 表格转换 async function convertTable() { let tableStr = await navigator.clipboard.readText(); let parser = new DOMParser(); let doc = parser.parseFromString(tableStr, "text/html"); let tableDom = doc?.querySelector("table"); let trs = tableDom?.querySelectorAll("tr"); let status = doc && tableDom && trs; if (!status) { showMessage("操作失败"); return; } // 获取表格的行数 let rowNum = trs.length; // 获取表格的列数 let firstRow = trs[0].querySelectorAll("td"); let colNum = firstRow.length; for (let td of firstRow) { if (td.getAttribute("colspan")) { let colspan = td.getAttribute("colspan"); colNum += parseInt(colspan) - 1; } } // 创建一个二维数组,用来放置表格的数据 let tableData = []; for (let i = 0; i < rowNum; i++) { let tempArr = new Array(colNum).fill(null); tableData.push(tempArr); } // 索引差值 let gap = 0; // 被合并的单元格——填充此字符串 let emptyData = `{: class="fn__none"}`; // 逐行解析表格,得到二维数组 for (let [rowIndex, tr] of trs.entries()) { let tds = tr.querySelectorAll("td"); gap = 0; row: for (let colIndex = 0; colIndex < tds.length; colIndex++) { let td = tds[colIndex]; let rowspan = td.getAttribute("rowspan"); let colspan = td.getAttribute("colspan"); let content = td.innerText; while (tableData[rowIndex][colIndex + gap] == emptyData) { gap++; } if (!rowspan && !colspan) { tableData[rowIndex][colIndex + gap] = content; } else { rowspan = parseInt(rowspan); colspan = parseInt(colspan); let a = new Array(colspan).fill(emptyData); for (let i = 0; i < rowspan; i++) { tableData[rowIndex + i].splice(colIndex + gap, colspan, ...a); } tableData[rowIndex][colIndex + gap] = content + `{: colspan="${colspan}" rowspan="${rowspan}"}`; gap = gap + colspan - 1; } } } // 将数组中的数据组合成表格模板 let templateStr = ""; for (let [index, row] of tableData.entries()) { templateStr += "|"; for (let item of row) { templateStr += item + "|"; } templateStr += "\n"; if (index === 0) { templateStr = templateStr + "|" + ":-------: |".repeat(colNum) + "\n"; } } // 将表格模板对应字符串写入到剪切板 patseIntoClipboard(templateStr); } // 顶栏添加一个按钮 const barMode = document.getElementById("barMode"); barMode.insertAdjacentHTML( "beforebegin", '<div id="convertTable" class="toolbar__item b3-tooltips b3-tooltips__se" aria-label="表格转换" ></div>' ); const convertBtn = document.getElementById("convertTable"); convertBtn.style.width = "auto"; convertBtn.innerHTML = `<svg t="1679417318794" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2816" width="32" height="32"><path d="M885.3 957.3H140.7c-42.2 0-76.5-34.3-76.5-76.5V136.3c0-42.2 34.3-76.5 76.5-76.5h744.6c42.2 0 76.5 34.3 76.5 76.5v744.6c-0.1 42.1-34.3 76.4-76.5 76.4z m-744.6-851c-16.5 0-29.9 13.4-29.9 29.9v744.6c0 16.5 13.4 29.9 29.9 29.9h744.6c16.5 0 29.9-13.4 29.9-29.9V136.3c0-16.5-13.4-29.9-29.9-29.9H140.7z" fill="#7D7D7D" p-id="2817"></path><path d="M938.5 315.8h-851V91.1c0-4.4 3.6-8 8-8h835c4.4 0 8 3.6 8 8v224.7z" fill="#CBCBCB" p-id="2818"></path><path d="M961.7 339H64.3V136.3c0-42.2 34.3-76.5 76.5-76.5h744.6c42.2 0 76.5 34.3 76.5 76.5V339z m-850.9-46.5h804.4V136.3c0-16.5-13.4-29.9-29.9-29.9H140.7c-16.5 0-29.9 13.4-29.9 29.9v156.2zM938.5 644.8h-851c-12.9 0-23.3-10.4-23.3-23.3 0-12.8 10.4-23.3 23.3-23.3h851c12.9 0 23.3 10.4 23.3 23.3-0.1 12.9-10.5 23.3-23.3 23.3z" fill="#7D7D7D" p-id="2819"></path><path d="M363.4 957.3c-12.9 0-23.3-10.4-23.3-23.3V315.8c0-12.8 10.4-23.3 23.3-23.3s23.3 10.4 23.3 23.3V934c0 12.9-10.4 23.3-23.3 23.3zM662.6 957.3c-12.9 0-23.3-10.4-23.3-23.3V315.8c0-12.8 10.4-23.3 23.3-23.3s23.3 10.4 23.3 23.3V934c0 12.9-10.5 23.3-23.3 23.3z" fill="#7D7D7D" p-id="2820"></path></svg>`; convertBtn.addEventListener( "click", (e) => { convertTable(); e.stopPropagation(); e.preventDefault(); }, true ); })();
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    24670 引用 • 101246 回帖
1 操作
someone69799 在 2023-03-23 21:07:29 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
请输入回帖内容 ...