使用Handsontable实现动态表格和下载表格

news2025/7/19 18:24:57

1.效果

2.实现代码

首先要加载Handsontable,在示例中我是cdn的方式引入的,vue的话需要下载插件

      let hot = null;
      var exportPlugin = null;
      function showHandsontable(param) {
        const container = document.getElementById("hot-container");
        // 如果已有实例,先销毁
        if (hot) {
          hot.destroy();
        }
        hot = new Handsontable(container, {
          data: [], // 初始为空
          colHeaders: true, // 动态列头
          rowHeaders: true, // 动态行头
          width: "100%",
          height: 800,
          licenseKey: "non-commercial-and-evaluation", // 免费版许可证
          contextMenu: true, // 启用右键菜单
          manualColumnResize: true, // 允许调整列宽
          manualRowResize: true, // 允许调整行高
          filters: true, // 启用筛选
          dropdownMenu: true, // 启用下拉菜单
          columnSorting: true, // 启用列排序
          stretchH: "all", // 列宽自适应
          afterChange: function (changes, source) {
            if (source === "edit") {
              console.log("数据已修改:", changes);
            }
          },
        });
      }
      showHandsontable();

点击后开始加载数据,注意colHeaders,rowHeaders,是行和列的名称,是数组格式

updateSettings:更新表格数据和表头

loadData:重新加载数据

      document
        .getElementById("load-data")
        .addEventListener("click", async function () {
          try {
            const response = await mockApiCall();
            console.log(response, "这时候弄-");

            // 更新表格数据和表头
            hot.updateSettings({
              colHeaders: response.headers.columns,
              rowHeaders: response.headers.rows,
            });
            hot.loadData(response.data);
            exportPlugin = hot.getPlugin("exportFile");
            console.log("数据加载成功");
          } catch (error) {
            console.error("加载数据失败:", error);
          }

3.下载表格

主要用到downloadFile和hot.getPlugin("exportFile")下载格式为csv,目前在Handsontable官网没有看到可以下载xlsx格式的,可能需要xlsx插件

   button.addEventListener("click", () => {
        //下载表格的数据
        exportPlugin.downloadFile("csv", {
          bom: false,
          columnDelimiter: ",",
          columnHeaders: true,//显示表头
          exportHiddenColumns: true,
          exportHiddenRows: true,
          fileExtension: "csv",
          filename: "Handsontable-CSV-file_[YYYY]-[MM]-[DD]",
          mimeType: "text/csv",
          rowDelimiter: "\r\n",
          rowHeaders: true,
        });

        //改为下载报表接口数据
      });

4.完整代码


<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>动态表格示例 - Handsontable</title>
    <!-- <script src="./handsontable.full.min.js"></script>
    <link rel="stylesheet" href="./handsontable.full.min.css" /> -->
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/handsontable/15.0.0/handsontable.full.min.js"
      integrity="sha512-3Os2SFklHFmIWzqQsBOmpA9fYBiar8ASBI4hqgeUKttdJ6lDWli7W+JmXyN8exab8NOpiYT441s6hfqX6Tx+WA=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    ></script>
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/handsontable/15.0.0/handsontable.full.min.css"
      integrity="sha512-reELraG6l/OUbRy0EnDh2RxkanfohOkWJX7afyUG1aGHv49SA9uqrAcJOMhyCNW6kcwbnhePc6JKcdUsQxmjvw=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    />
    <style>
      body {
        font-family: Arial, sans-serif;
        margin: 20px;
      }
      #hot-container {
        margin-top: 20px;
      }
      .controls {
        margin-bottom: 10px;
      }
      button {
        padding: 8px 12px;
        margin-right: 10px;
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <h1>动态表格示例</h1>
    <div class="controls">
      <button id="load-data">加载数据</button>
      <button id="export-file">下载表格</button>
    </div>
    <div id="hot-container"></div>

    <!-- <script src="app.js"></script> -->
    <script type="text/javascript">
      let hot = null;
      var exportPlugin = null;
      function showHandsontable(param) {
        const container = document.getElementById("hot-container");
        // 如果已有实例,先销毁
        if (hot) {
          hot.destroy();
        }
        hot = new Handsontable(container, {
          data: [], // 初始为空
          colHeaders: true, // 动态列头
          rowHeaders: true, // 动态行头
          width: "100%",
          height: 800,
          licenseKey: "non-commercial-and-evaluation", // 免费版许可证
          contextMenu: true, // 启用右键菜单
          manualColumnResize: true, // 允许调整列宽
          manualRowResize: true, // 允许调整行高
          filters: true, // 启用筛选
          dropdownMenu: true, // 启用下拉菜单
          columnSorting: true, // 启用列排序
          stretchH: "all", // 列宽自适应
          afterChange: function (changes, source) {
            if (source === "edit") {
              console.log("数据已修改:", changes);
            }
          },
        });
      }
      showHandsontable();

      // 加载数据按钮事件
      document
        .getElementById("load-data")
        .addEventListener("click", async function () {
          try {
            const response = await mockApiCall();
            console.log(response, "这时候弄-");

            // 更新表格数据和表头
            hot.updateSettings({
              colHeaders: response.headers.columns,
              rowHeaders: response.headers.rows,
            });
            hot.loadData(response.data);
            exportPlugin = hot.getPlugin("exportFile");
            console.log("数据加载成功");
          } catch (error) {
            console.error("加载数据失败:", error);
          }
        });
      function mockApiCall() {
        return new Promise((resolve) => {
          // 模拟网络延迟
          setTimeout(() => {
            const mockData = {
              headers: {
                columns: ["ID", "姓名", "年龄", "部门", "薪资"],
                rows: Array.from({ length: 15 }, (_, i) => `员工${i + 1}`),
              },
              data: Array.from({ length: 15 }, (_, i) => [
                i + 1000,
                `员工${i + 1}`,
                Math.floor(Math.random() * 20) + 20,
                ["研发部", "市场部", "人事部", "财务部"][
                  Math.floor(Math.random() * 4)
                ],
                (Math.random() * 10000 + 5000).toFixed(2),
              ]),
            };
            resolve(mockData);
          }, 500);
        });
      }

      const button = document.querySelector("#export-file");

      button.addEventListener("click", () => {
        //下载表格的数据
        exportPlugin.downloadFile("csv", {
          bom: false,
          columnDelimiter: ",",
          columnHeaders: false,
          exportHiddenColumns: true,
          exportHiddenRows: true,
          fileExtension: "csv",
          filename: "Handsontable-CSV-file_[YYYY]-[MM]-[DD]",
          mimeType: "text/csv",
          rowDelimiter: "\r\n",
          rowHeaders: true,
        });

        //改为下载报表接口数据
      });
    </script>
  </body>
</html>

文章到此结束,希望对你有所帮助~

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

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

相关文章

Action:Update your application‘s configuration

在使用Maven项目时&#xff0c;有一个报错信息是&#xff1a;Update your applications configuration 这类问题&#xff0c;就是我们的application.yml文件 或者 application.properties文件 内容哪里写错了 最有可能就是对齐方式有问题

【计算机网络】IP地址

IPv4 五类地址 1.0.0.0 ~ 126.255.255.255A类子网8位&#xff0c;主机24位128.0.0.0 ~ 191.255.255.255B类子网16位&#xff0c;主机16位192.0.0.0 ~ 223.255.255.255C类子网24位&#xff0c;主机8位224.0.0.0 ~ 239.255.255.255D类不分网络地址和主机地址&#xff0c;作为组播…

Rundeck 介绍及安装:自动化调度与执行工具

Rundeck介绍 概述&#xff1a;Rundeck 是什么&#xff1f; Rundeck 是一款开源的自动化调度和任务执行工具&#xff0c;专为运维场景设计&#xff0c;帮助工程师通过统一的平台管理和执行跨系统、跨节点的任务。它由 PagerDuty 维护&#xff08;2016 年收购&#xff09;&#…

vue element使用el-table时,切换tab,table表格列项发生错位问题

展示问题 问题描述&#xff1a;使用el-table的fixed"right"属性后&#xff0c;如果切换tab时&#xff0c;回出现最后一列错误的问题 官网提供解决方法&#xff1a;doLayout 需要注意的事项&#xff1a;我这里是通过组件使用的table组件&#xff0c;涉及多层组件封装…

第十二章 Python语言-大数据分析PySpark(终)

目录 一. PySpark前言介绍 二.基础准备 三.数据输入 四.数据计算 1.数据计算-map方法 2.数据计算-flatMap算子 3.数据计算-reduceByKey方法 4.数据计算-filter方法 5.数据计算-distinct方法 6.数据计算-sortBy方法 五.数据输出 1.输出Python对象 &#xff08;1&am…

AD相同网络的铜皮和导线连接不上

出现这样的情况是不是很烦恼&#xff0c;明明是相同的网络连接不上&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; 直接修改铜皮属性&#xff08;选择所有相同这个选项&#xff09; 这样就可以连接上了

keil修改字体无效,修改字体为“微软雅黑”方法

在网上下载了微软雅黑字体&#xff0c;微软雅黑参考下载链接 结果在Edit->Configuration中找不到这个字体 这个时候可以在keil的安装目录中找到UV4/global.prop文件 用记事本打开它进行编辑&#xff0c;把字体名字改成微软雅黑 重新打开keil就发现字体成功修改了。 这个…

【网络编程】从零开始彻底了解网络编程(三)

本篇博客给大家带来的是网络编程的知识点. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 王子,公主请阅&#x1f680; 要开心要快乐顺便进步 TCP流…

NVIDIA --- 端到端自动驾驶

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、传统驾驶模型二、NVIDIA的端到端驾驶模型1.基本模型2.自查讯向量3.通用框架 总结 前言 端到端自动驾驶指的是系统接收来自摄像头雷达和激光雷达的原始传感…

CSRF请求伪造

该漏洞主要是关乎于用户&#xff0c;告诫用户不可乱点击链接&#xff0c;提升自我防范&#xff0c;才能不落入Hacker布置的陷阱&#xff01; 1. cookie与session 简单理解一下两者作用 1.1. &#x1f36a; Cookie&#xff1a;就像超市的会员卡 存储位置&#xff1a;你钱包里…

(一)单机架构、应用数据分离架构、应用服务集群架构

文章目录 明确为什么要学习架构的演进单机架构什么是单机架构单机架构的模型单机架构的优缺点优点缺点 单机架构的技术案例 应用数据分离架构什么是应用数据分离架构架构模型应用数据分离架构的优缺点优点缺点 技术案例 应用服务集群架构什么是应用服务集群架构架构模型应用服务…

Python数据分析案例72——基于股吧评论数据的情感分析和主题建模(LDA)

背景 好久没更新了&#xff0c;最近忙其他去了。最近股市波动太大&#xff0c;看了不少新闻的评论。抽空写了个股吧评论数据的LDA建模和情感分析&#xff0c;简单写到博客上来更新一下。 数据来源 上证指数(000001)股吧_上证指数怎么样_分析讨论社区— 数据来源上述网站的东…

力扣-160.相交链表

题目描述 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返…

【C++】特殊类的设计、单例模式以及Cpp类型转换

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 上篇文章&#xff1a; C 智能指针使用&#xff0c;以及shared_ptr编写 下篇文章&#xff…

050_基于springboot的音乐网站

一、系统架构 前端&#xff1a;vue | element-ui | html | jquery | css | ajax 后端&#xff1a;springboot | mybatis 环境&#xff1a;jdk1.8 | mysql | maven | nodejs | idea 二、代码及数据 三、功能介绍 01. web端-注册 02. web端-登录 03. web…

【论文阅读】平滑量化:对大型语言模型进行准确高效的训练后量化

论文题目&#xff1a;SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models 论文地址&#xff1a;[2211.10438] SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models 代码地址&#xff1a;http…

【资料推荐】LVDS Owner’s Manual

一份年代有些久远的技术资料&#xff0c;但是内容全面且经典&#xff01; 本用户手册提供了很多有用的信息&#xff0c;首先简要概述了三种最常见的高速接口技术&#xff1a;LVDS&#xff08;包括B-LVDS和M-LVDS&#xff09;、CML和LVPECL&#xff0c;并对其相应的特性进行了分…

ARM Cortex-M (STM32)如何调试HardFault

目录 步骤 1: 实现一个有效的 HardFault 处理程序 步骤 2: 复现 HardFault 并使用调试器分析 步骤 3: 解读故障信息 步骤 4: 定位并修复源代码 HardFault 是 ARM Cortex-M 处理器中的一种异常。当处理器遇到无法处理的错误&#xff0c;或者配置为处理特定类型错误&#xff…

黑马 redis面试篇笔记

redis主从 version: "3.2"services:r1:image: rediscontainer_name: r1network_mode: "host"entrypoint: ["redis-server", "--port", "7001"]r2:image: rediscontainer_name: r2network_mode: "host"entrypoint:…

DBdriver使用taos数据库

首先创建连接 连接后比如数据库里有三个库 选择其中的hypon 选中localhost&#xff0c;右键sql编辑器&#xff0c;打开sql控制台 就插入了一条数据