当前位置: 首页 > news >正文

vue3 用xlsx 解决 excel 低版本office无法打开问题

  • 需求背景
  • 解决思路
  • 解决效果
  • 将json导出为excel
  • 将table导为excel
  • 导出样式

需求背景

原使用 vue3-json-excel ,导致在笔记本office环境下,出现兼容性问题

 <vue3-json-excel class="export-btn" :fetch="excelGetList" :fields="jsonFields" header="告警配置列表" name="告警配置列表.xls" type="xls"><span>批量导出</span></vue3-json-excel>

生成的.xls文件,提示文件格式和扩展名不匹配,文件可能已损坏或不安全在这里插入图片描述
生成的.xlsx文件,提示文件格式或文件扩展名无效
在这里插入图片描述

解决思路

既然 vue3-json-excel 达不到效果,就改用xlsx

解决效果

在这里插入图片描述

将json导出为excel

/*** 将json数据导出为excel* @param {object} options* @param {[]} data 数据源 // {'供热系统': "大唐热电供热系统", '供热面积(万m²)': 34.099, '分布式水泵数量': 0, '当前供热系统': "大唐热电供热系统"}* @param {string} fileName 文件名称* @param [] keySort  字段排序 // ['供热系统', '供热面积(万m²)', '分布式水泵数量','当前供热系统']* @param {string} sheetName sheet名称* @param {boolean} titleNum 表头数*/
import XLSXStyle from "xlsx-style-vite" //"^0.0.2"
import FileSaver from "file-saver";// "^2.0.5"
import * as XLSX from "xlsx";//"^0.17.0",export const exportToExcel = (data, fileName, keySort, sheetName = "sheet1", titleNum = 1) => {// const sheet = XLSX.utils.json_to_sheet(data)const temp = data.map(item => {const arr = []keySort.forEach(k => arr.push(item[k]))return arr})temp.unshift(keySort)const sheet = XLSX.utils.aoa_to_sheet(temp)const wb = {SheetNames: [sheetName],Sheets: {[sheetName]: sheet}}const range = XLSX.utils.decode_range(wb.Sheets[sheetName]['!ref']);//单元格边框样式const borderStyle = {top: {style: "thin",color: {rgb: "000000"}},bottom: {style: "thin",color: {rgb: "000000"}},left: {style: "thin",color: {rgb: "000000"}},right: {style: "thin",color: {rgb: "000000"}}};const cWidth = [];for (let C = range.s.c; C < range.e.c + 1; ++C) {   //SHEET列let len = 100; //默认列宽const len_max = 400; //最大列宽for (let R = range.s.r; R <= range.e.r; ++R) {  //SHEET行const cell = {c: C, r: R};                    //二维 列行确定一个单元格const cell_ref = XLSX.utils.encode_cell(cell);  //单元格 A1、A2if (wb.Sheets[sheetName][cell_ref]) {if (R < titleNum) {wb.Sheets[sheetName][cell_ref].s = {  //设置第一行单元格的样式 stylefont: {sz: 14, // 标题字号color: {rgb: '060B0E'},// 颜色bold: true//加粗},alignment: {horizontal: 'center',vertical: 'center',},fill: {fgColor: {rgb: 'E4E4E4'}, // 背景},border: borderStyle,//用上面定义好的边框样式};} else {wb.Sheets[sheetName][cell_ref].s = {alignment: {horizontal: 'center',vertical: 'center',},border: borderStyle,//用上面定义好的边框样式};}//动态自适应:计算列宽const va = JSON.parse(JSON.stringify(wb.Sheets[sheetName][cell_ref].v || ''));const card1 = JSON.parse(JSON.stringify(va.toString())).match(/[\u4e00-\u9fa5]/g); //匹配中文let card11 = "";if (card1) card11 = card1.join("")const card2 = JSON.parse(JSON.stringify(va.toString())).replace(/([^\u0000-\u00FF])/g, "");  //剔除中文let st = 0;if (card11) st += card11.length * 20  //中文字节码长度if (card2) st += card2.length * 10  //非中文字节码长度if (st > len) len = st;}}cWidth.push({'wpx': len > len_max ? len_max : len});     //列宽}wb.Sheets[sheetName]['!cols'] = cWidth;const wopts = {bookType: 'xlsx', bookSST: false, type: 'binary'};const wbout = XLSXStyle.write(wb, wopts); //一定要用XLSXStyle不要用XLSX,XLSX是没有格式的!FileSaver(new Blob([s2ab(wbout)], {type: ""}), fileName + '.xlsx');function s2ab(s) {const buf = new ArrayBuffer(s.length);const view = new Uint8Array(buf);for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;return buf;}
}

将table导为excel

/*** 将table导出为excel* @param {object} options* @param {[]} table 表格元素* @param {string} fileName 文件名称* @param {string} sheetName sheet名称* @param {boolean} titleNum 表头数*/
export const exportTableToExcel = (dom, fileName, sheetName = "sheet1", titleNum = 1) => {const wb = XLSX.utils.table_to_book(dom, {sheet: sheetName, raw: true});const range = XLSX.utils.decode_range(wb.Sheets[sheetName]['!ref']);//单元格边框样式const borderStyle = {top: {style: "thin",color: {rgb: "000000"}},bottom: {style: "thin",color: {rgb: "000000"}},left: {style: "thin",color: {rgb: "000000"}},right: {style: "thin",color: {rgb: "000000"}}};const cWidth = [];for (let C = range.s.c; C < range.e.c + 1; ++C) {   //SHEET列let len = 100; //默认列宽const len_max = 400; //最大列宽for (let R = range.s.r; R <= range.e.r; ++R) {  //SHEET行const cell = {c: C, r: R};                    //二维 列行确定一个单元格const cell_ref = XLSX.utils.encode_cell(cell);  //单元格 A1、A2if (wb.Sheets[sheetName][cell_ref]) {// if (R == 0){if (R < titleNum) {wb.Sheets[sheetName][cell_ref].s = {  //设置第一行单元格的样式 stylefont: {sz: 14,color: {rgb: '060B0E'},bold: true},alignment: {horizontal: 'center',vertical: 'center',},fill: {fgColor: {rgb: 'E4E4E4'},},border: borderStyle,//用上面定义好的边框样式};} else {wb.Sheets[sheetName][cell_ref].s = {alignment: {horizontal: 'center',vertical: 'center',},border: borderStyle,//用上面定义好的边框样式};}//动态自适应:计算列宽const va = JSON.parse(JSON.stringify(wb.Sheets[sheetName][cell_ref].v || ''));const card1 = JSON.parse(JSON.stringify(va.toString())).match(/[\u4e00-\u9fa5]/g); //匹配中文let card11 = "";if (card1) {card11 = card1.join("")}const card2 = JSON.parse(JSON.stringify(va.toString())).replace(/([^\u0000-\u00FF])/g, "");  //剔除中文let st = 0;if (card11) {st += card11.length * 20  //中文字节码长度}if (card2) {st += card2.length * 10  //非中文字节码长度}if (st > len) {len = st;}}}if (len > len_max) {//最大宽度len = len_max;}cWidth.push({'wpx': len});     //列宽}wb.Sheets[sheetName]['!cols'] = cWidth.slice(1, -1);// 删除列-----重点-----0就是第一列。。// wb.Sheets[sheetName]['!cols'][0] = {hidden: true}deleteCol(wb.Sheets[sheetName], 0)deleteCol(wb.Sheets[sheetName], cWidth.length - 1)// 合并列// wb.Sheets[sheetName]["!merges"] = [//   {  //合并A1A2单元格//     s: {//s为开始//       c: 0,//开始列//       r: 0//开始取值范围//     },//     e: {//e结束//       c: 1,//结束列//       r: 0//结束范围//     }//   }// ]const wopts = {bookType: 'xlsx', bookSST: false, type: 'binary'};const wbout = XLSXStyle.write(wb, wopts); //一定要用XLSXStyle不要用XLSX,XLSX是没有格式的!FileSaver(new Blob([s2ab(wbout)], {type: ""}), fileName + '.xlsx');function encodeCell(r, c) {return XLSX.utils.encode_cell({r, c});}// 删除行function deleteRow(ws, index) {const range = XLSX.utils.decode_range(ws['!ref']);for (let row = index; row < range.e.r; row++) {for (let col = range.s.c; col <= range.e.c; col++) {ws[encodeCell(row, col)] = ws[encodeCell(row + 1, col)];}}range.e.r--;ws['!ref'] = XLSX.utils.encode_range(range.s, range.e);}// 删除列function deleteCol(ws, index) {const range = XLSX.utils.decode_range(ws['!ref']);for (let col = index; col < range.e.c; col++) {for (let row = range.s.r; row <= range.e.r; row++) {ws[encodeCell(row, col)] = ws[encodeCell(row, col + 1)];}}range.e.c--;ws['!ref'] = XLSX.utils.encode_range(range.s, range.e);}function s2ab(s) {const buf = new ArrayBuffer(s.length);const view = new Uint8Array(buf);for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;return buf;}
}

导出样式

应粉丝要求,附上导出样式

import {h} from "vue";
import {ElMessageBox} from "element-plus";ElMessageBox({title: '导出Excel表格',draggable: true,showCancelButton: true,showConfirmButton: false,message: h('div', null, [ // 这里用到了h函数h(ElButton, { text: true, type: 'primary', innerHTML: '导出选中数据', onClick: assignExport }),h(ElButton, { text: true, type: 'success', innerHTML: '导出所有数据', onClick: allExport })]),cancelButtonText: '取消',
})
// 导出
const assignExport = () =>{console.log(111)
}
const allExport = () =>{console.log(222)
}

在这里插入图片描述

相关文章:

vue3 用xlsx 解决 excel 低版本office无法打开问题

需求背景解决思路解决效果将json导出为excel将table导为excel导出样式 需求背景 原使用 vue3-json-excel &#xff0c;导致在笔记本office环境下&#xff0c;出现兼容性问题 <vue3-json-excel class"export-btn" :fetch"excelGetList" :fields"js…...

Java后端底座从无到有的搭建(随笔)

文章目录 开发模式的演变草创时期1.0时期&#xff08;基座时期&#xff09;1.1时期&#xff08;低代码时期&#xff09;2.0时期&#xff08;无代码时期&#xff09; 前言&#xff1a;本文是笔者在初创公司&#xff0c;一年多来Java后端服务底座搭建过程的总结&#xff0c;如有不…...

Rust介绍与开发环境搭建

Rust 是一种系统编程语言&#xff0c;它专注于内存安全、并发和性能。它是由 Mozilla 开发的&#xff0c;并得到了许多社区的广泛支持。Rust 的设计理念是“安全 by default”&#xff0c;这意味着你不需要特殊的工具或技巧来编写安全的代码。 Rust 的主要特点&#xff1a; 内…...

本地TCP通讯(C++)

概要 利用TCP技术&#xff0c;实现本地ROS1和ROS2的通讯。 服务端代码 头文件 #include <ros/ros.h> #include "std_msgs/String.h" #include "std_msgs/Bool.h" #include <iostream> #include <cstring> #include <unistd.h>…...

docker 安装jenkins

使用 Docker 安装 Jenkins 是一种快速、方便的方法&#xff0c;可以避免本地环境的复杂依赖。以下是通过 Docker 安装 Jenkins 的基本步骤&#xff1a; 安装 Docker&#xff1a; 如果你的系统尚未安装 Docker&#xff0c;请先安装 Docker。对于 Ubuntu 系统&#xff0c;可以通过…...

电脑黑屏什么都不显示怎么办 电脑开机黑屏不显示任何东西的4种解决办法

相信有很多网友都有经历电脑开机黑屏不显示任何东西&#xff0c;找了很多方法都没处理好&#xff0c;其实关于这个的问题&#xff0c;首先还是要了解清楚开机黑屏的原因&#xff0c;才能够对症下药&#xff0c;下面大家可以跟小编一起来看看怎么解决吧 电脑开机黑屏不显示任何…...

MT8781核心板_MTK8781安卓核心板规格参数

MT8781安卓核心板以其强大的性能和高效的能耐备受瞩目。其八核CPU架构包括(2x Cortex-A76 2.2GHz 6x Cortex-A55 2.0GHz)&#xff0c;以及高性能的Arm Mali G57级GPU。同时&#xff0c;配备高达2,133MHz的LPDDR4X内存和快速的UFS 2.2级存储&#xff0c;大大加速了数据访问速…...

HTML知识点

HTML 【一】HTML简介 【1】什么是HTML HTML是一种用于创建网页结构和内容的超文本标记语言&#xff0c;它是构建网页的基础。为了让浏览器正确渲染页面&#xff0c;我们必须遵循HTML的语法规则。浏览器在解析网页时会将HTML代码转换为可视化的页面&#xff0c;所以我们在浏览…...

聊聊分库分表

文章导读 背景介绍 随着互联网技术的发展&#xff0c;数据量呈爆炸性增长。大数据量的业务场景中&#xff0c;数据库成为系统性能瓶颈的一个主要因素。当单个数据库包含了太多数据或过高的访问量时&#xff0c;会出现查询缓慢、响应时间长等问题&#xff0c;严重影响用户体验。…...

小米标准模组+MCU 快速上手开发(二)——之模组串口调试

小米标准模组MCU 开发笔记之固件调试 背景技术名词简介● 小米IoT开发者平台● 小米IoT 模组● 固件● OTA● CRC32 固件双串口调试● MHCWB6S-IB 模组资料下载● MHCWB6S-IB 模组管脚图● 上电调试 背景 小米标准模组MCU的开发过程中&#xff0c;由于部分官方资料较为古早&am…...

Ubuntu22.04和Windows10双系统安装

概要 本篇演示Ubuntu22.04和Windows10双系统的安装。先安装Ubuntu22.04&#xff0c;再安装Windows10。 一、说明 1、电脑 笔者的电脑品牌是acer(宏碁/宏基) 电脑开机按F2进入BIOS 电脑开机按F12进入Boot Manager 2、U盘启动盘 需要用到两个U盘启动盘 &#xff08;1&a…...

重新安装VSCode后,按住Ctrl(or Command) 点击鼠标左键不跳转问题

重新安装VSCode后&#xff0c;按住Ctrl&#xff08;or Command&#xff09; 点击鼠标左键不跳转问题 原因&#xff1a;重新安装一般是因为相应编程语言的插件被删除了或还没有下载。 本次是由于Python相关的插件被删除了&#xff0c;因此导致Python无法跳转。 解决办法 在vs…...

QPaint绘制自定义仪表盘组件01

网上抄别人的&#xff0c;只是放这里自己看一下&#xff0c;看完就删掉 ui Dashboard.pro QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomm…...

华为笔记本原厂系统镜像恢复安装教程方法

1.安装方法有两种&#xff0c;一种是用PE安装&#xff0c;一种是华为工厂包安装&#xff08;安装完成自带F10智能还原&#xff09; 若没有原装系统文件&#xff0c;请在这里远程恢复安装&#xff1a;https://pan.baidu.com/s/166gtt2okmMmuPUL1Fo3Gpg?pwdm64f 提取码:m64f …...

互联网高科技公司领导AI工业化,MatrixGo加速人工智能落地

作者&#xff1a;吴宁川 AI&#xff08;人工智能&#xff09;工业化与AI工程化正在引领人工智能的大趋势。AI工程化主要从企业CIO角度&#xff0c;着眼于在企业生产环境中规模化落地AI应用的工程化举措&#xff1b;而AI工业化则从AI供应商的角度&#xff0c;着眼于以规模化方式…...

Apache服务

目录 引言 一、常见的http服务程序 &#xff08;一&#xff09;lls &#xff08;二&#xff09;nginx &#xff08;三&#xff09;Apache &#xff08;四&#xff09;Tomcat 二、Apache特点 三、Apache服务的安装 &#xff08;一&#xff09;yum安装及配置文件 1.配置…...

【Spring连载】使用Spring Data访问 MongoDB(二)----Template API

【Spring连载】使用Spring Data访问 MongoDB&#xff08;二&#xff09;----Template API 一、方便的方法二、执行回调函数Execute Callbacks三、Fluent API四、异常转换五、域类型映射六、配置6.1 默认读取首选项Read Preference6.2 WriteResultChecking策略6.3 默认写安全Wri…...

手写table表格(一表头多数据)

手写table表格&#xff08;一表头多数据&#xff09; <template><div class"table-info"><div class"info-list"><div class"header-wrapper"><div class"columns-title" v-for"(i, k) in columns&q…...

python3 flask 实现对config.yaml文件的内容的增删改查,并重启服务

config.yaml配置文件内容 功能就是userpass下的用户名和密码做增删改查&#xff0c;并重启hy2服务 auth:type: userpassuserpass:csdn: csdnlisten: :443 masquerade:proxy:rewriteHost: trueurl: https://www.bing.com/type: proxy tls:cert: /root/hyst*****马赛克******er…...

ADO世界之“对象”

目录 一、Command 对象 1.Command 对象 2.语法 3.属性 4.方法 5.集合 二、Connection 对象 1.Connection 对象 2.语法 3.属性 4.方法 5.事件 6.集合 三、Error 对象 1.Error 对象 2.语法 3.属性 四、Parameter 对象 1.Field 对象 2.语法 3.属性 4.方法 …...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...