luckyexcel 编辑预览excel文件

news2024/12/22 17:13:04

luckyexcel 编辑预览excel文件

支持后端传文件流预览编辑,也支持选择本地文件编辑预览

看效果

在这里插入图片描述

上代码

<template>
  <div style="margin: 30px">
    <div class="button-box2">
      <div>
        <div style="color: red">当前弹框不要修改列名称,如需修改,请去列管理页面修改列。</div>
      </div>

      <div>
        <a-space>
          <!-- <input id="uploadBtn" type="file" @change="loadExcel3" /> -->
          <a-button type="primary" @click="downExcel">导出模板</a-button>
          <a-upload
            v-model:file-list="data.fileList"
            accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            :customRequest="customUpload"
            name="file"
            :multiple="false"
            :showUploadList="false"
          >
            <a-button :loading="data.clientLoading" type="primary">客户端导入</a-button>
          </a-upload>
          <a-button
            type="primary"
            :loading="data.serverLoading"
            @click="() => (modal.visible = true)"
            >服务端导入</a-button
          >
          <!-- <a-dropdown>
            <template v-slot:overlay>
              <a-menu>
                <a-menu-item key="1">
                  <a-upload
                    v-model:file-list="data.fileList"
                    accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                    :customRequest="customUpload"
                    name="file"
                    :multiple="false"
                    :showUploadList="false"
                  >
                    <div :loading="data.clientLoading">客户端导入</div>
                  </a-upload>
                </a-menu-item>
                
                <a-menu-item key="2">
                  <div :loading="data.serverLoading" @click="() => (modal.visible = true)">
                    服务端导入
                  </div>
                </a-menu-item>
              </a-menu>
            </template>
            <a-button type="primary">
              导入预览(如果这样写的话就要把loading放到这里,统一一个变量就好了)
              <DownOutlined />
            </a-button>
          </a-dropdown> -->
        </a-space>
      </div>
    </div>

    <div id="luckysheet"></div>
    <div class="button-box">
      <a-space>
        <a-button @click="cancel"> 取消 </a-button>
        <a-button type="primary" :loading="loading" @click="downloadExcel">确定 </a-button>
      </a-space>
    </div>
    <div class="tips">
      <div style="color: red" v-if="data.isShowDataType">
        测序方法请填写:Nanopore pod5,Nanopore fast5,Nanopore fastq,齐碳
        fastq,PacBio_CCS,PacBio_CLR,华大,illumina,ABI,其他
      </div>
      <div style="color: red" v-if="data.isShowDataType">
        类型请填写:细菌,病毒,真菌,16S,宏基因组,动植物,转录组,人源,其他
      </div>
      <div style="color: red" v-if="data.isShowDataType">
        日期请按照YYYY-MM-DD格式填写,如:2024-01-01
      </div>
    </div>
    <a-modal
      :visible="modal.visible"
      title="选择文件"
      width="1020px"
      @ok="fileOk"
      @cancel="() => (modal.visible = false)"
      zIndex="1000"
      destroyOnClose
    >
      <FileSelect />
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
import { reactive, onMounted, watch } from 'vue';
import * as Api from '/@/serve/api/samples/samples';
import { exportExcel } from '/@/utils/utils/exceljs';
import FileSelect from '/@/components/FileSelector/index.vue';
import { DownOutlined } from '@ant-design/icons-vue';
import LuckyExcel from 'luckyexcel';
import xlsx from 'node-xlsx';

import { message } from 'ant-design-vue';
const emit = defineEmits(['cancel', 'batchAddData']);
const props = defineProps({
  headers: {
    type: Array,
    default: () => [],
  },
  loading: {
    type: Boolean,
    default: false,
  },
});
const modal = reactive({
  visible: false,
});
const cancel = () => {
  luckysheet.exitEditMode(); // 退出编辑模式
  emit('cancel', '');
};
//服务器导入确定
const fileOk = () => {
  let selectPath = localStorage.getItem('nowSelector');
  if (selectPath) {
    if (selectPath.indexOf(' ') != -1) {
      message.warning('所选路径不能包含空格');
      return;
    }
    if (selectPath.slice(-5).includes('.xlsx')) {
      loadExcel2(selectPath);
      modal.visible = false;
    } else {
      message.info('请选择xlsx文件');
    }
  }
};
const loadExcel2 = (filePath: string) => {
  let params = { filePath };
  Api.xlsxFile(params)
    .then((res: any) => {
      const blob = new Blob([res], {
        // 设置返回的文件类型
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      });
      let file = new window.File([blob], 'fileName.xlsx', {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      });
      data.serverLoading = true;
      loadExcel([file]);
    })
    .catch(() => {
      message.error('error');
    });
};
const loadExcel3 = (evt: any) => {
  loadExcel(evt.target.files);
};
//自定义上传
const customUpload = (info: any) => {
  data.clientLoading = true;
  loadExcel([info.file]);
};

const isFunction = (val: Function) => {
  return Object.prototype.toString.call(val).slice(8, -1) === 'Function';
};

const loadExcel = (files: any) => {
  //通过接口获取文件流,将文件流转为file文件,
  if (files == null || files.length == 0) {
    message.info('没有文件等待导入');
    return;
  }
  let name = files[0].name;
  let suffixArr = name.split('.'),
    suffix = suffixArr[suffixArr.length - 1];
  if (suffix != 'xlsx') {
    message.error('目前只支持导入xlsx文件');
    return;
  }
  LuckyExcel.transformExcelToLucky(files[0], function (exportJson, luckysheetfile) {
    if (exportJson.sheets == null || exportJson.sheets.length == 0) {
      message.error('读取excel文件内容失败,目前不支持xls文件!');
      return;
    }
    //销毁原有的表格
    isFunction(luckysheet?.destroy) && luckysheet.destroy();
    luckysheet.create({
      container: 'luckysheet', //luckysheet is the container id
      lang: 'zh', // 设定表格语言
      showinfobar: false,
      data: exportJson.sheets,
      title: exportJson.info.name,
      userInfo: exportJson.info.name.creator,
    });
    console.log('start loading');
    data.clientLoading = false;
    data.serverLoading = false;
  });
};
const downExcel = () => {
  let result = xlsx.build([{ name: 'sheet1', data: [props.headers] }]);
  const ab = Buffer.from(result, 'binary');
  const blob = new Blob([ab]);
  const blobUrl = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = blobUrl;
  a.download = '模版.xlsx';
  a.click();
  window.URL.revokeObjectURL(blobUrl);
  // exportExcel(luckysheet.getAllSheets(), '模板');
};
const downloadExcel = () => {
  // console.log(luckysheet.getAllSheets());
  // exportExcel(luckysheet.getAllSheets(), '下载');
  luckysheet.exitEditMode(); // 退出编辑模式
  let data = luckysheet.getAllSheets()[0].celldata;
  console.log(data);

  let result: any[] = [];
  data.forEach((item: any) => {
    if (result.length > item.r) {
      let tempArray = result[item.r];
      // console.log('item.c', item.c);

      tempArray[item.c] = item.v.m;
    } else {
      let tempArray = [];
      for (let i = 0; i < props.headers.length; i++) {
        tempArray.push(undefined);
      }
      tempArray[item.c] = item.v.m;
      result.push(tempArray);
    }
  });
  // let result2 = result.map((item: any) => {
  //   return item.slice(0, props.headers.length);
  // });
  // console.log(result2);
  emit('batchAddData', result);
};

const data = reactive({
  options: {},
  fileList: [],
  clientLoading: false,
  serverLoading: false,
  isShowDataType: false,
});
// !!! create luckysheet after mounted
onMounted(() => {
  drawSheet();
});

watch(
  () => props.headers,
  (n) => {
    drawSheet();
  },
);

const drawSheet = () => {
  console.log('111');

  data.isShowDataType = props.headers.includes('测序方法');
  let celldata = props.headers.map((item: any, index: number) => {
    let con = {
      r: 0,
      c: index,
      v: {
        bl: 1,
        ct: { fa: 'General', t: 'g' },
        ht: 0,
        v: item,
        m: item,
      },
    };
    return con;
  });
  data.options = {
    container: 'luckysheet',
    lang: 'zh', // 设定表格语言
    showinfobar: false,
    data: [
      {
        name: 'Sheet1', //工作表名称
        color: '', //工作表颜色
        index: 0, //工作表索引
        status: 1, //激活状态
        order: 0, //工作表的下标
        hide: 0, //是否隐藏
        row: 36, //行数
        column: 36, //列数
        defaultRowHeight: 39, //自定义行高
        defaultColWidth: 146, //自定义列宽
        celldata, //初始化使用的单元格数据
        config: {
          merge: {}, //合并单元格
          rowlen: {}, //表格行高
          columnlen: {}, //表格列宽
          rowhidden: {}, //隐藏行
          colhidden: {}, //隐藏列
          borderInfo: {}, //边框
          authority: {}, //工作表保护
        },
        scrollLeft: 0, //左右滚动条位置
        scrollTop: 0, //上下滚动条位置
        luckysheet_select_save: [], //选中的区域
        calcChain: [], //公式链
        isPivotTable: false, //是否数据透视表
        pivotTable: {}, //数据透视表设置
        filter_select: {}, //筛选范围
        filter: null, //筛选配置
        luckysheet_alternateformat_save: [], //交替颜色
        luckysheet_alternateformat_save_modelCustom: [], //自定义交替颜色
        luckysheet_conditionformat_save: {}, //条件格式
        frozen: {}, //冻结行列配置
        chart: [], //图表配置
        zoomRatio: 1, // 缩放比例
        image: [], //图片
        showGridLines: 1, //是否显示网格线
        dataVerification: {}, //数据验证配置
      },
      // {
      //   name: 'Sheet2',
      //   color: '',
      //   index: 1,
      //   status: 0,
      //   order: 1,
      // celldata: [
      //     {
      //       r: 0,
      //       c: 0,
      //       v: {
      //         v: '暂时淀粉',
      //         m: '暂时淀粉',
      //       },
      //     },
      //     {
      //       r: 0,
      //       c: 1,
      //       v: {
      //         v: 1,
      //         ct: {
      //           fa: 'General',
      //           t: 'n',
      //         },
      //         m: '1',
      //       },
      //     },
      //     {
      //       r: 1,
      //       c: 0,
      //       v: {
      //         v: 10,
      //         ct: {
      //           fa: 'General',
      //           t: 'n',
      //         },
      //         m: '10',
      //       },
      //     },
      //     {
      //       r: 1,
      //       c: 1,
      //       v: {
      //         v: 11,
      //         ct: {
      //           fa: 'General',
      //           t: 'n',
      //         },
      //         m: '11',
      //       },
      //     },
      //   ],
      //   config: {},
      // },
    ],
  };

  isFunction(luckysheet?.destroy) && luckysheet.destroy();
  luckysheet.create(data.options);
};
</script>

<style scoped>
#luckysheet {
  /* position: relative; */
  width: 79vw;
  height: 70vh;
}
.button-box {
  /* margin: 20px; */
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}
.button-box2 {
  margin: 20px;
  display: flex;
  /* justify-content: flex-end; */
  justify-content: space-between;
}
.tips {
  margin-top: -30px;
}
:deep(.luckysheet-wa-editor) {
  overflow: hidden;
}
:deep(.luckysheet-stat-area) {
  background-color: transparent;
}
</style>
<style>
#chat-assistant-container {
  display: none;
}
</style>

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

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

相关文章

【精通SDL之----SDL_RenderReadPixels截屏】

SDL_RenderReadPixels截屏 前言一、SDL_RenderReadPixels简介二、问题现象三、规避方案1. 离屏纹理2. ding! *灵光一现* 前言 最近使用SDL2在鸿蒙系统(Harmoney OS)上截取视频播放过程中的数据&#xff0c;发现捕获的数据为空&#xff0c;然在windows上却可以正常捕获&#xff…

Linux 内核源码分析---网络层分析

版本(version)&#xff1a;指定所用 IP 协议的版本&#xff0c;该字段有效值为 4 或 6&#xff1b; IP首部长度(IHL)&#xff1a;定义首部的长度&#xff0c;由于选项数量可变&#xff1b; 服务区分&#xff1a;用于更复杂协议选项&#xff1b; 长度&#xff1a;指定分组的总长…

AI技术重塑招聘流程

一、引言 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术正以前所未有的速度渗透到社会的各个领域&#xff0c;其中&#xff0c;人力资源管理领域也不例外。在全员招聘这一关键环节中&#xff0c;AI技术的应用不仅极大地提高了招聘效率&#xff0c;还…

【Java数据结构】---Queue

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 文章目录 前言队列Queue队列的模拟…

fme处理空间数据入门v0

概述 本教程是最最最基本的fme处理空间数据内容&#xff0c;给新同事介绍我以前是怎么干活用的&#xff0c;基本啥有用的东西。 本教程主要说如何在 FME Workbench中创建模板文件&#xff08;一般我们把fme写的工作空间就叫模板&#xff09;&#xff0c;教程里面主要是利用GI…

Linux2.6内核进程调度队列详细讲解

上图是 Linux2.6 内核中进程队列的数据结构&#xff0c;之间关系也已经给大家画出来&#xff0c;方便大家理解。 一个 CPU 拥有一个 runqueue。 Linux真正的调度方式是通过runqueue进行调度的&#xff0c;我们知道进程的优先级范围是根据nice值确定的&#xff0c;而nice值的范围…

怎么配置Datagrip中字体的大小,修改注释的颜色呢

新手刚安装Datagrip时&#xff0c;都会遇到怎么调字体大小的问题&#xff0c;接下来解决一下吧 具体步骤&#xff1a; 1.进入Datagrip的操作窗口后&#xff0c;点击左上方的菜单栏中file(文件)。 2.在文件中点击设置setting。 3.在设置窗口点击Editor,再点击Font。 4.在Fo…

.[[Hoeosi@airmail.cc]].rntc勒索病毒数据怎么处理|数据解密恢复

导言&#xff1a; 近年来&#xff0c;勒索病毒&#xff08;也称为勒索软件&#xff09;已成为网络安全领域的一大威胁。其中&#xff0c;.[[Hoeosiairmail.cc]].rntc勒索病毒作为一种新型恶意软件&#xff0c;通过加密用户的重要文件并要求支付赎金来解锁&#xff0c;给个人和…

深度学习 —— 个人学习笔记20(转置卷积、全卷积网络)

声明 本文章为个人学习使用&#xff0c;版面观感若有不适请谅解&#xff0c;文中知识仅代表个人观点&#xff0c;若出现错误&#xff0c;欢迎各位批评指正。 三十九、转置卷积 import torch from torch import nndef trans_conv(X, K):h, w K.shapeY torch.zeros((X.shape[…

Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task02笔记

1 前言 本次是学习内容是Datawhale AI夏令营第四期-AIGC文生图方向的学习笔记。 2 AIGC简介 AIGC&#xff08;Artificial Intelligence Generated Content&#xff09;即人工智能生成内容&#xff0c;即人工智能通过学习大量的数据&#xff0c;来实现自动生成各种内容&#xf…

仿RabbitMQ实现消息队列

前言&#xff1a;本项目是仿照RabbitMQ并基于SpringBoot Mybatis SQLite3实现的消息队列&#xff0c;该项目实现了MQ的核心功能&#xff1a;生产者、消费者、中间人、发布、订阅等。 源码链接&#xff1a;仿Rabbit MQ实现消息队列 目录 前言&#xff1a;本项目是仿照Rabbi…

JVM运行时数据区之虚拟机栈

【1】概述 Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xff09;&#xff0c;早期也叫Java栈。每个线程在创建时都会创建一个虚拟机栈&#xff0c;其内部保存一个个的栈帧&#xff08;Stack Frame&#xff09;&#xff0c;对应着一次次的Java方法调用。 栈是运行…

World of Warcraft [CLASSIC] 80 WLK [Gundrak] BUG

World of Warcraft [CLASSIC] 80 WLK [Gundrak] BUG 魔兽世界怀旧版&#xff0c;80级&#xff0c;5人副本古达克&#xff0c;科技队伍&#xff08;BUG队伍&#xff09; 副本有两个门口 这样看&#xff0c;是不是觉得很怪。是的&#xff0c;和图1刚好相反的。 因此应该翻转180…

24电赛H题总结

一、题目 题目链接&#xff1a;自动行驶小车&#xff08;H题&#xff09; 我们截取一些重要信息 1. 小车行驶场地示意图 2.要求 二、赛题分析 技术挑战与准备 MCU熟悉度&#xff1a;尽管TI MSPM0系列MCU在使用上类似于STM32CUBEIDEKeil&#xff0c;但其开发环境也需要熟悉。因…

数据结构入门——04栈

1.栈 栈是限制在一端进行插入操作和删除操作的线性表&#xff08;俗称堆栈&#xff09; 允许进行操作的一端称为“栈顶”&#xff0c;另一固定端称为“栈底”&#xff0c;当栈中没有元素时称为“空栈”。 栈的特点 &#xff1a;后进先出LIFO&#xff08;Last In First Out&a…

支持I2C接口、抗干扰性强、14通道触摸按键的电容式触摸芯片-GTX314L

电容式触摸芯片 - GTX314L是具有多通道触发传感器的14位触摸传感器系列&#xff0c;它是通过持续模式提供中断功能和唤醒功能&#xff0c;广泛适用于各种控制面板应用&#xff0c;可直接兼容原机械式轻触按键的处理信号。 GTX314L芯片内部采用特殊的集成电路&#xff0c;具有高…

C++进阶-智能指针

1. 为什么需要智能指针&#xff1f; 下面我们先分析一下下面这段程序有没有什么内存方面的问题&#xff1f;提示一下&#xff1a;注意分析MergeSort函数中的问题。 int div() {int a, b;cin >> a >> b;if (b 0)throw invalid_argument("除0错误");retur…

【C语言】内存管理

C语言-内存管理 一、C进程内存布局二、栈内存1、存储在栈内存中的参数有哪些&#xff1f;2、栈内存的特点&#xff1f; 三、静态数据四、数据段与代码段五、堆内存 一、C进程内存布局 \qquad 任何一个程序&#xff0c;正常运行都需要内存资源&#xff0c;用来存放诸如变量、常量…

第九届“创客中国”武汉区域赛正式启幕 灵途科技勇夺前三,晋级决赛!

8月8日&#xff0c;第九届“创客中国”武汉区域赛正式启幕&#xff0c;首场聚焦先进制造领域。灵途科技勇夺先进制造领域专场企业组前三名&#xff0c;成功晋级决赛。 “创客中国”大赛是工业和信息化部组织开展的双创赛事活动&#xff0c;以构建产业链协同发展为出发点&#…

Win10 VisualStudio 2022编译ollvm 13.x

VisualStudio配置 1&#xff0c;正常配置C桌面环境 2&#xff0c;在单个组件中选择用于Windows得C Cmake工具 下载OLLVM13.x https://github.com/heroims/obfuscator/tree/llvm-13.x 解压后进入文件夹&#xff0c;命令行输入 cmake -G “Visual Studio 17 2022” -DLLVM_EN…