上传word表格识别出table表格 转为二维数组并显示(vue)

一 、在main.js引入全局JS

import JSZip from 'jszip';
export default {async extractWordTablesToArrays(file, callback) {const Zip = new JSZip();try {// 解压 Word 文档const zip = await Zip.loadAsync(file);const documentXml = await zip.file("word/document.xml").async("string");// 解析 XMLconst parser = new DOMParser();const documentDoc = parser.parseFromString(documentXml, "application/xml");// 获取命名空间const namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";// 获取所有表格const tables = documentDoc.getElementsByTagNameNS(namespace, "tbl");const allTables = []; // 存储所有表格的二维数组if (!tables || tables.length === 0) {console.warn("未找到表格内容,请检查 XML 结构");return [];}for (const table of tables) {const rows = table.getElementsByTagNameNS(namespace, "tr");const tableArray = []; // 当前表格的二维数组for (const row of rows) {const cells = row.getElementsByTagNameNS(namespace, "tc");const rowArray = []; // 当前行的数据// 存储已合并的单元格let colSpanInfo = [];for (let i = 0; i < cells.length; i++) {const cell = cells[i];let cellText = "";// const paragraphs = cell.getElementsByTagNameNS(namespace, "p");const paragraphs = cell.getElementsByTagName("w:p");// 检查合并单元格属性const gridSpan = cell.getElementsByTagNameNS(namespace, "gridSpan")[0];const vMerge = cell.getElementsByTagNameNS(namespace, "vMerge")[0];// 获取合并信息let colspan = gridSpan ? parseInt(gridSpan.getAttribute("w:val"), 10) : 1;let rowspan = 1;if (vMerge && vMerge.getAttribute("w:val") === "restart") {rowspan = 2; // 假设合并两行} else if (vMerge && !vMerge.getAttribute("w:val")) {continue; // 如果是合并单元格的继续部分,则跳过}// 为当前单元格初始化计数器const currentLevelNumbers = {};for (const paragraph of paragraphs) {// 提取段落编号let listPrefix = "";// 初始化当前段落文本let paragraphText = listPrefix ? `${listPrefix} ` : "";const runs = paragraph.getElementsByTagName("w:r");for (const run of runs) {let textContent = "";const texts = run.getElementsByTagName("w:t");for (const text of texts) {textContent += text.textContent;}// 检查格式const rPr = run.getElementsByTagName("w:rPr")[0];let formattedText = textContent;if (rPr) {const bold = rPr.getElementsByTagName("w:b").length > 0;const italic = rPr.getElementsByTagName("w:i").length > 0;const vertAlignElement = rPr.getElementsByTagName("w:vertAlign")[0];if (bold) {formattedText = `<b>${formattedText}</b>`;}if (italic) {formattedText = `<i>${formattedText}</i>`;}if (vertAlignElement) {const vertAlign = vertAlignElement.getAttribute("w:val");if (vertAlign === "superscript") {formattedText = `<sup>${formattedText}</sup>`;} else if (vertAlign === "subscript") {formattedText = `<sub>${formattedText}</sub>`;}}}paragraphText += formattedText;}// 处理换行符const breaks = paragraph.getElementsByTagName("w:br");for (const br of breaks) {paragraphText += "<br>";}cellText += paragraphText; // 将段落文本添加到单元格文本}// 更新合并单元格的信息if (colSpanInfo[i]) {colspan = colSpanInfo[i].colspan;}// 保存当前单元格信息rowArray.push({text: cellText,colspan: colspan,rowspan: rowspan});// 记录跨列合并if (colspan > 1) {for (let j = 1; j < colspan; j++) {colSpanInfo[i + j] = { colspan: 0 }; // 用 0 填充后续的列合并}}}tableArray.push(rowArray); // 添加当前行到表格数组}allTables.push(tableArray); // 添加当前表格到所有表格数组}console.log("解析后的二维数组:", allTables);callback(allTables); // 返回处理后的 HTML} catch (error) {console.error("解析 Word 文件失败:", error);return [];}},getWordTablesThumbnails(tables, callback) {let combinedHtml = `<div style="display: flex; flex-wrap: wrap; gap: 16px; justify-content: start;">`;// 遍历每个表格,生成缩略图tables.forEach((table, index) => {let tableHtml = `<div style="border: 1px solid #ccc; padding: 8px; width: 200px; height: 150px; overflow: hidden; position: relative; cursor: pointer;"οnclick="document.getElementById('table-modal-${index}').style.display='block';"><div style="transform: scale(0.3); transform-origin: top left; position: absolute; width: 1000px;"><table border="1" style="border-collapse: collapse; width: 100%; text-align: center; table-layout: auto;">`;table.forEach((row) => {tableHtml += `<tr>`;// 遍历单元格row.forEach((cell) => {tableHtml += `<td colspan="${cell.colspan || 1}" rowspan="${cell.rowspan || 1}" style=""><span > ${cell.text}</span> </td>`;});tableHtml += `</tr>`;});tableHtml += `</table></div></div><!-- 模态框显示原始表格 --><div id="table-modal-${index}" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); z-index: 9999;"οnclick="this.style.display='none';"><div style="background: #fff; margin: 50px auto; height: 80%;padding: 20px; max-width: 80%;box-sizing:border-box;max-width: 80%; overflow: auto;">`;// 原始大小的表格内容tableHtml += `<table border="1" style="border-collapse: collapse; width: 100%; text-align: center; table-layout: auto;">`;table.forEach((row) => {tableHtml += `<tr>`;// 遍历单元格row.forEach((cell) => {tableHtml += `<td colspan="${cell.colspan || 1}" rowspan="${cell.rowspan || 1}" style=""><span > ${cell.text}</span> </td>`;});tableHtml += `</tr>`;});tableHtml += `</table></div></div>`;combinedHtml += tableHtml;});combinedHtml += `</div>`;const container = document.createElement("div");container.innerHTML = combinedHtml;callback(container.innerHTML);},},

二、页面中 点击图片上传本地文件

<template><div><img src="@/assets/img/word.png" alt="" style="width: 30px; height: 30px" @click="clickUpload" /><el-dialogappend-to-bodytitle="Add Academic Integrity Committee":visible.sync="addVisible"width="80%":close-on-click-modal="false"><div v-html="tablesHtml" class="wordTableHtml"></div></el-dialog></div>
</template>
<script>
export default {data() {return {tablesHtml: '',tables: [], // 保存解析后的表格数据addVisible: false};},components: {},methods: {addVisCancle() {this.addVisible = false;},clickUpload() {this.tables = [];var that = this;const input = document.createElement('input');input.type = 'file';input.accept = '.docx'; // 限制为 Word 文件input.addEventListener('change', function () {const file = input.files[0];if (file) {const reader = new FileReader();reader.onload = function (e) {that.$commonJS.extractWordTablesToArrays(file, function (wordTables) {console.log('tablesHtml at line 61:', wordTables);that.tables = wordTables;that.$commonJS.getWordTablesThumbnails(wordTables, function (html) {console.log('html at line 78:', html);that.tablesHtml = html;that.addVisible = true;});that.$emit('tables', that.tables, html);});};reader.readAsArrayBuffer(file);}});input.click();},}
};
</script>```以下样式看情况 因为我需要 上标 下标 粗体 字体 的样式
```css
<style scoped>
::v-deep .wordTableHtml b span {font-weight: bold !important;
}
::v-deep .wordTableHtml i span {font-style: italic !important;
}
::v-deep .wordTableHtml sub span {vertical-align: sub;
}
::v-deep .wordTableHtml sup span {vertical-align: super;
}
::v-deep .wordTableHtml sub {vertical-align: sub !important;
}
::v-deep .wordTableHtml sup {vertical-align: super !important;
}
::v-deep .wordTableHtml span[style*='vertical-align: super'] {vertical-align: super !important;
}
::v-deep .wordTableHtml span[style*='vertical-align: sub'] {vertical-align: sub !important;
}
::v-deep .wordTableHtml table {border: 0px !important;border-collapse: collapse; /* 去除单元格间隙 */width: auto;margin: 0 auto !important;table-layout: auto; /* 自动调整列宽 */text-align: left;font-family: 'Charis SIL' !important;font-size: 7.5pt !important;mso-font-kerning: 1pt !important;line-height: 10pt !important;mos-line-height: 10pt !important;
}
::v-deep .wordTableHtml table td,
.wordTableHtml table th::v-deep {padding: 5px;text-align: left !important;word-wrap: break-word; /* 长单词自动换行 */word-break: break-word;font-family: 'Charis SIL' !important;font-size: 7.5pt !important;mso-font-kerning: 1pt !important;line-height: 10pt !important;mos-line-height: 10pt !important;
}
::v-deep .wordTableHtml table tbody tr td {text-align: left !important;border-left: none !important;mso-border-left-alt: none !important;border-right: none !important;mso-border-right-alt: none !important;border-top: none;mso-border-top-alt: none !important;border-bottom: none !important;mso-border-bottom-alt: none !important;border: 1px dashed #dcdfe6 !important;border-left: 1px dashed #dcdfe6 !important;border-right: 1px dashed #dcdfe6 !important;word-break: keep-all !important;/* text-align: justify !important;  */
}
::v-deep .wordTableHtml table tr td p {display: flex;text-align: left !important;align-items: center;margin: 0;font-family: 'Charis SIL' !important;font-size: 7.5pt !important;mso-font-kerning: 1pt !important;line-height: 10pt !important;mos-line-height: 10pt !important;
}
::v-deep .wordTableHtml table span {color: #000000;text-align: left !important;font-family: 'Charis SIL' !important;font-size: 7.5pt !important;mso-font-kerning: 1pt !important;line-height: 10pt !important;mos-line-height: 10pt !important;
}
::v-deep .wordTableHtml table .color-highlight {color: rgb(0, 130, 170) !important;font-family: 'Charis SIL' !important;font-size: 7.5pt !important;mso-font-kerning: 1pt !important;line-height: 10pt !important;mos-line-height: 10pt !important;
}
::v-deep .wordTableHtml table tr:first-child td {border-top: 1px solid #000 !important;border-bottom: 1px solid #000 !important;
}
::v-deep .wordTableHtml table tr:last-of-type td {border-bottom: 1px solid #000 !important;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/35523.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

在做题中学习(77):快排

解法&#xff1a;快排 思路&#xff1a; 1.快排排一趟&#xff0c;递归分出来的左区间和右区间&#xff08;一趟的思想&#xff0c;看我的前一个文章&#xff1a;颜色分类题解&#xff09; 2.递归&#xff1a;想清楚 函数头 和 返回条件怎么写 3.优化&#xff1a;等概率的取…

AUTO TECH China 2025 华南展:探索汽车技术的新纪元

AUTO TECH China 2025 华南展&#xff1a;探索汽车技术的新纪元 随着科技的日新月异&#xff0c;汽车行业正经历着前所未有的变革。从电动化、智能化到网联化&#xff0c;每一项新技术的应用都在重塑我们对汽车的认知。为了展示这些令人激动的创新成果&#xff0c;我们荣幸地宣…

C# RSA加密和解密,RSA生成私钥和公钥

C# RSA加密和解密&#xff0c;RSA生成私钥和公钥&#xff08;使用XML格式秘钥&#xff09; 目录 前言生成xml格式的公钥和私钥 PrivateKeyPublicKey测试加密、解密 方案1&#xff1a;RSA公钥加密&#xff0c;RSA私钥解密方案2&#xff1a;RSA私钥加密&#xff0c;RSA私钥解密…

指标加权评价方法

文章目录 层次分析法&#xff08;Analytic Hierarchy Process, AHP&#xff09;熵权法原理计算方法 Technique for Order Preference by Similarity to Ideal Solution(TOPSIS, 优劣解距离法)原理计算方法 层次分析法&#xff08;Analytic Hierarchy Process, AHP&#xff09; …

React第十七章(useRef)

useRef 当你在React中需要处理DOM元素或需要在组件渲染之间保持持久性数据时&#xff0c;便可以使用useRef。 import { useRef } from react; const refValue useRef(initialValue) refValue.current // 访问ref的值 类似于vue的ref,Vue的ref是.value&#xff0c;其次就是vu…

SpringBoot 赋能家乡特色推荐系统:高效架构与前沿技术集成

1 绪 论 1.1课题背景与意义 在Internet高速发展的今天&#xff0c;计算机的应用几乎完全覆盖我们生活的各个领域&#xff0c;互联网在经济&#xff0c;生活等方面有着举足轻重的地位&#xff0c;成为人们资源共享&#xff0c;信息快速传递的重要渠道。在中国&#xff0c;网上管…

国际知名会计事务所安永造访图为科技,探索财务管理全球化新路径

今日&#xff0c;全球领先的安永会计师事务所&#xff08;以下简称“安永”&#xff09;合伙人造访了图为信息科技&#xff08;深圳&#xff09;有限公司&#xff08;以下简称“图为科技”&#xff09;。 安永就财务管理工作的全球化战略提供专业指导意见&#xff0c;并为双方…

Java 实现手机号码归属地查询

1.pom坐标 <dependency><groupId>com.googlecode.libphonenumber</groupId><artifactId>geocoder</artifactId><version>2.205</version></dependency> 2.代码 package test;import com.alibaba.excel.util.StringUtils; im…

SIP系列七:ICE框架(P2P通话)

我的音视频/流媒体开源项目(github) SIP系列目录 目录 一、NAT 1、NAT介绍 2、NAT类型 2.1、 完全圆锥型NAT 2.2、受限圆锥型NAT 2.3、端口受限圆锥型NAT 2.4、对称NAT 3、NAT打洞 3.1、不同一NAT下 3.2、同一NAT下 二、ICE 三、ICE中的SDP 至此&#x…

python桌面工具

用处 使用该工具可以将excel内容转成SQL语句&#xff0c;可以使用到一些SQL的报表平台可以将json文件转成xlsx格式文件 前期准备 安装库 pip install pandas -i https://mirrors.aliyun.com/pypi/simplepip install wxpython -i https://mirrors.aliyun.com/pypi/simplepip i…

【Golang】Go语言编程思想(一):接口

接口 接口的概念 现在我们要实现一个函数&#xff0c;用于对给定的 url 进行解析&#xff0c;具体的代码实现如下&#xff1a; package mainimport ("fmt""io""net/http" )func retrieve(url string) string {resp, err : http.Get(url)if er…

SAP SD 如何设置交货单数量可修改为0

在日常运维中&#xff0c;销售订单可以被reject&#xff0c;但是交货单只能被物理删除 但是粗暴的物理删除&#xff0c;又会使得单据不连续&#xff0c;出现问题不好追溯 所以我们就可以通过将废弃的交货单的数量置为0 配置如下&#xff1a; C表示&#xff0c;创建的时候不可…

记一次由docker容器使得服务器cpu占满密码和密钥无法访问bug

Bug场景&#xff1a; 前几天在服务器上部署了一个免费影视网站&#xff0c;这个应用需要四个容器&#xff0c;同时之前的建站软件workpress也是使用docker部署的&#xff0c;也使用了三个容器。在使用workpress之前&#xff0c;我将影视软件的容器全部停止。 再使用workpress…

Matlab R2024b 中文版 下载及安装教程

点击下方链接下载安装包 Matlab R2024b 中文版安装包点击下载https://mp.weixin.qq.com/s/Kq2j1dQLdULOVV9vrA6pkA 安装教程 1.通过上方链接下载软件&#xff0c;鼠标右键【MATLAB R2024b(64bit)】压缩包&#xff0c;选择解压到MATLAB R2024b(64bit)。 2.双击进入解压后的文…

2024年12月6日Github流行趋势

项目名称&#xff1a;lobe-chat 项目维护者&#xff1a;arvinxx, semantic-release-bot, canisminor1990, lobehubbot, renovate项目介绍&#xff1a;一个开源的现代化设计的人工智能聊天框架。支持多AI供应商&#xff08;OpenAI / Claude 3 / Gemini / Ollama / Qwen / DeepSe…

韩企研学团造访图为科技:共探人工智能创新前沿

今日&#xff0c;一支由韩国知名企业研学专家组成的代表团莅临图为科技深圳总部&#xff0c;展开了一场深度技术交流与研讨活动。 此次访问旨在通过实地探访中国领先的科技企业&#xff0c;促进中韩两国在科技创新领域的深入合作与交流。 韩国游学团合影 图为科技作为一家在人…

Vulnhub---kioptirx4 udf手工提权

个人博客 WuTongSec 打点 nmap -sP 192.168.128.0/24 找机器 nmap -P- 192.168.128.135 端口快扫 nmap -min-rate 10000 -sV -sC -O 192.168.128.135 脚本并没有扫出 什么洞 dirsearch -u http://192.168.128.135 目录扫描 三个200 那就先上web看看 web是应该登录框 在pas…

基于RISC-V的HSM方案

安全之安全(security)博客目录导读 本篇博客&#xff0c;我们聚焦RISC-V 2024中国峰会上RISC-V的一个HSM&#xff08;Hardware Security Module&#xff09;实现方案&#xff0c;来自芯来科技王松老师。 关于RISC-V TEE(可信执行环境)的相关方案&#xff0c;如感兴趣可参考RIS…

【C++探索学习】第十九弹——进程替换:深入解析操作系统中的进程替换机制

Linux学习笔记&#xff1a; https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言&#xff1a; 在Linux操作系统中&#xff0c;进程替换&#xff08;Process Replacement&#xff09;是一个重要的概念&#xff0c;它允许程序通过系统调…

[软件工程]八.软件演化

8.1什么是软件演化 由于种种不可避免的原因&#xff0c;系统开发完成后的软件需要进行修改来适应变更的需求&#xff0c;我们对软件的修改就叫软件演化。 8.2为什么软件会演化 由于业务的变更或者为了满足用户期待的改变&#xff0c;使得对已有的系统的新需求浮现出来。由于…