vue前端接包(axios)+ 前端导出excel(xlsx-js-style)

devtools/2024/10/18 12:52:25/
// 先在请求处加上:    
responseType: 'arraybuffer', // 指定响应类型为ArrayBuffer
 const data = new Uint8Array(response.data); // 将ArrayBuffer转换为Uint8Arrayconst val = { columns: [], data: [] }let offset = 0; // 用于跟踪当前解析到的位置while (offset < data.length) {// 确保当前偏移量可读取8个字节if (offset + 8 > data.length) {console.warn('字节数不足,无法读取偏移处的长度:', offset);break; // 不够数据,退出循环}// 获取前8个字节,计算包长度const lengthHex = String.fromCharCode.apply(null, data.slice(offset, offset + 8));const packLength = parseInt(lengthHex, 16); // 转换为十进制// 确保当前偏移量可读取完整的数据包if (offset + 8 + packLength > data.length) {console.warn('字节数不足,无法在偏移处读取数据包:', offset);break; // 不够数据,退出循环}// 使用TextDecoder来处理JSON内容const decoder = new TextDecoder('utf-8');const jsonBody = decoder.decode(data.slice(offset + 8, offset + 8 + packLength)); // 获取JSON内容// 解析并存储数据包try {const packetData = JSON.parse(jsonBody); // 解析JSONif (offset == 0) {val.columns = packetData.columns;}val.data.push(...packetData.data);} catch (error) {console.error('Error parsing JSON:', error, jsonBody);}// 更新偏移量offset += 8 + packLength; // 移动到下一个包的起始位置}// 现在 allPackets 包含所有解析后的数据包console.log('All parsed packets:', val);const worker = new Worker(new URL('./export-worker.ts', import.meta.url), { type: 'module' });worker.postMessage({ data: val });worker.onmessage = (e) => {if (e && e.data && e.data.t == "export") {e.stopPropagation();e.preventDefault();// data will be the Uint8Array from the workerconst res = e.data.v;downloadExcelFile(new Blob([res], { type: "application/octet-stream" }), row.TaskName + '-核查结果.xlsx');window.$message?.success('导出成功!');}operateLoading.value = false;worker.terminate(); // 终止 Worker};worker.onerror = (error) => {console.error('Worker error:', error);operateLoading.value = false;worker.terminate(); // 终止 Worker};

export-worker.ts

import * as XLSX_STYLE from 'xlsx-js-style';interface Column {name: string;headerText: string;
}interface Data {columns: Column[];data: any[][];
}interface ExportMessage {t: string;v: any;
}self.onmessage = async (event: MessageEvent) => {const { data }: { data: Data } = event.data;// 这里放置处理导出逻辑的代码const highlightFields: string[][] = [];const problemFieldsIndex: number = data.columns.findIndex(col => col.name === 'ProblemFields');// 移除 ProblemFields 字段if (problemFieldsIndex !== -1) {data.columns.splice(problemFieldsIndex, 1);}const formattedData = data.data.map((row: any[]) => {const problemFields = row[problemFieldsIndex];highlightFields.push(problemFields.split(','));row.splice(problemFieldsIndex, 1);// const rowData: { [key: string]: any } = {};// data.columns.forEach((col: Column, index: number) => {//   rowData[col.headerText] = row[index];// });return row;});const BATCH_SIZE = 30000; // 定义每批处理的数据大小// 添加标题行const header = data.columns.map(col => col.headerText);// 设置样式const headerCellStyle = {font: { name: 'Arial', sz: 10, bold: true, color: { rgb: "FFFFFF" } },  // 白色字体fill: { fgColor: { rgb: "808080" } }, // 灰色背景alignment: { vertical: 'center', horizontal: 'center' }};const cellStyle = {font: { name: 'Arial', sz: 10 },alignment: { vertical: 'center', horizontal: 'center', wrapText: true }};const highlightStyle = {fill: { fgColor: { rgb: "FFFF00" } }, // 黄色背景font: { name: '宋体', sz: 11 },alignment: { vertical: 'center', horizontal: 'center', wrapText: true },border: {top: { style: 'thin', color: { rgb: "C3CBDD" } },bottom: { style: 'thin', color: { rgb: "C3CBDD" } },left: { style: 'thin', color: { rgb: "C3CBDD" } },right: { style: 'thin', color: { rgb: "C3CBDD" } }}};const ws = [];for (let i = 0; i < formattedData.length; i += BATCH_SIZE) {const worksheet = XLSX_STYLE.utils.aoa_to_sheet([header], { origin: 'A1' }); // 创建一个空工作表const batchData = formattedData.slice(i, i + BATCH_SIZE);// 添加批量数据到工作表末尾XLSX_STYLE.utils.sheet_add_aoa(worksheet, batchData, { skipHeader: true, origin: -1 });// 设置列宽、行高和样式// 设置每列的宽度(单位:字符)const wsCols: { wch: number }[] = new Array(data.columns.length).fill({ wch: 30 });worksheet['!cols'] = wsCols;worksheet['!cols'][0] = { wch: 50 };// 设置行高(单位:像素,通常建议设置为 20 或更高)worksheet['!rows'] = new Array(batchData + 1).fill({ hpt: 50 });worksheet['!rows'][0] = { hpt: 25 };// 应用样式到表头和普通单元格for (const col in worksheet) {if (col[0] === '!') continue; // 跳过元数据const cell = worksheet[col];// 设置表头样式if (data.columns.some(header => header.headerText === cell.v)) {cell.s = headerCellStyle;} else {cell.s = cellStyle; // 设置普通单元格样式}}// 根据 ProblemFields 高亮单元格batchData.forEach((row, rowIndex) => {const globalRowIndex = i + rowIndex; // 计算全局行索引highlightFields[globalRowIndex].forEach(problemField => {const colIndex = data.columns.findIndex(col => col.name === problemField); // 找到对应的列索引if (colIndex !== -1) {const cellRef = XLSX_STYLE.utils.encode_cell({ c: colIndex, r: rowIndex + 1 }); // 行号加1因为第一行为表头if (worksheet[cellRef]) {worksheet[cellRef].s = highlightStyle; // 应用高亮样式}}});});ws.push(worksheet);}// const worksheet = XLSX_STYLE.utils.json_to_sheet(formattedData, { header: data.columns.map(col => col.headerText) });const workbook = XLSX_STYLE.utils.book_new();const min = formattedData.length > BATCH_SIZE ? BATCH_SIZE : formattedData.length;ws.forEach((worksheet: any) => {XLSX_STYLE.utils.book_append_sheet(workbook, worksheet);});console.log("准备写入")const val = XLSX_STYLE.write(workbook, { type: "array", bookType: "xlsx", bookSST: true, compression: true });console.log("写入完成")self.postMessage({ t: "export", v: val } as ExportMessage);
};

http://www.ppmy.cn/devtools/126721.html

相关文章

C#中正则表达式

在C#中&#xff0c;正则表达式由 System.Text.RegularExpressions 命名空间提供&#xff0c;可以使用 Regex 类来处理正则表达式。以下是一些常见的用法及示例。 C# 中使用正则表达式的步骤&#xff1a; 引入命名空间&#xff1a; using System.Text.RegularExpressions; 创…

Go 1.19.4 命令调用、日志、包管理、反射-Day 17

1. 系统命令调用 所谓的命令调用&#xff0c;就是通过os&#xff0c;找到系统中编译好的可执行文件&#xff0c;然后加载到内存中&#xff0c;变成进程。 1.1 exec.LookPath&#xff08;寻找命令&#xff09; 作用&#xff1a; exec.LookPath 函数用于在系统的环境变量中搜索可…

arm架构ceph pacific部署

背景 合作伙伴实验室的华为私有云原来使用单点的nfs做为存储设备&#xff0c;现有两方面考量&#xff0c;业务需要使用oss了&#xff0c;k8s集群及其他机器也需要一套可扩展的分布式文件系统 部署ceph 初始机器配置规划 IP配置主机名Role10.17.3.144c8g1T数据盘ceph-node01…

深度学习-27-基于keras的深度学习建模预测全流程

文章目录 1 深度学习简介1.1 定义和应用场景1.2 基本原理1.2.1 神经网络1.2.2 激活函数1.2.3 损失函数1.2.4 优化算法1.3 深度学习建模预测全流程1.3.1 数据预处理1.3.2 模型构建1.3.3 训练模型1.3.4 模型评估1.3.5 模型优化1.3.6 模型部署2 手写数字识别应用2.1 加载数据2.2 数…

Qt通过QProcess调用第三方进程

我们在运行Qt程序时&#xff0c;有时需要调用第三方程序&#xff0c;这时就可以用QProcess类。具体如下&#xff1a; 一. 启用进程之前 我们需要在头文件中定义一个私有变量指针&#xff0c;为了使他能长时间运行&#xff0c;定义为指针。 #include <QProcess> class …

Java 项目如何连接并使用 SFTP 服务的示例详解

文章目录 1、SFTP介绍2、pom依赖3、SFTPUtil4、测试5、测试结果 1、SFTP介绍 SFTP&#xff08;Secure File Transfer Protocol&#xff09;是一种安全的文件传输协议&#xff0c;是SSH&#xff08;Secure Shell&#xff09;协议的一个子协议&#xff0c;设计用于加密和保护文件…

【Java知识】Java进阶-线程池深度解读

文章目录 线程池概述线程池的核心组件和概念&#xff1a;线程池的工作原理&#xff1a;线程池的创建&#xff1a;线程池的关闭&#xff1a;总结&#xff1a; 线程池种类以及用途以ScheduledThreadPool为例的类继承关系 拒绝策略有哪些&#xff1f;使用范例固定大小的线程池单线…

SAP SD学习笔记- 豆知识 - SAP中的英文 - SD中英文,日语,中文

SD的中部分中日英文对照。先收集&#xff0c;等以后再整理。 1&#xff0c;販売管理&#xff08;销售管理&#xff09; 日本語英語中国語受注伝票sales order销售订单出荷伝票delivery order交货订单ピッキングリストpicking list领货清单シップメント伝票shipment document发…