xlsx xlsx-style 使用和坑记录

1 安装之后报错

npm install xlsx --save

npm install xlsx-style --save

Umi运行会报错

自己代码

import XLSX from "xlsx";
import XLSXStyle from "xlsx-style";

const data = [
  [
    "demo1",
    "demo2",
    "demo3",
    "demo4",
    "demo5",
    "是否开启(填写注意: 0为否,1为是)",
  ],
  ["1", "2", "3", "4", "5", "0"],
];
const wsWidths = [20, 20, 20, 20, 20, 20];

const book = XLSX.utils.book_new(); //没有工作表的空工作簿
const workSheet = XLSX.utils.aoa_to_sheet(data);
if (Array.isArray(wsWidths) && wsWidths.length === columnNames[0].length) {
  workSheet["!cols"] = wsWidths.map((width) => ({ wch: width }));
}
if (merge) {
  /**
     *
      合并单元格:
      // s 意为 start ,即开始的单元格
      // r 是 row ,表示行号,从 0 计起
      // c 是 col ,表示列号,从 0 计起
      const merge = [
        // 纵向合并,范围是第1列的行1到行2
        { s: { r: 0, c: 0 }, e: { r: 1, c: 0 } },
        // 纵向合并,范围是第2列的行1到行2
        { s: { r: 0, c: 1 }, e: { r: 1, c: 1 } },
        // 横向合并,范围是第1行的列3到列5
        { s: { r: 0, c: 2 }, e: { r: 0, c: 4 } },
        // 横向合并,范围是第1行的列6到列11
        { s: { r: 0, c: 5 }, e: { r: 0, c: 10 } },
        // 横向合并,范围是第1行的列12到列17
        { s: { r: 0, c: 11 }, e: { r: 0, c: 16 } },
        // 横向合并,范围是第1行的列18到列23
        { s: { r: 0, c: 17 }, e: { r: 0, c: 22 } },
        // 横向合并,范围是第1行的列24到列29
        { s: { r: 0, c: 23 }, e: { r: 0, c: 28 } },
        // 横向合并,范围是第1行的列30到列35
        { s: { r: 0, c: 29 }, e: { r: 0, c: 34 } }
      ];
    */
  workSheet["!merges"] = merge;
}
const colKeys = Object.keys(workSheet).filter((k) => /[A-Z]/.test(k[0]));
styles.forEach((s, i) => {
  const t = columnNames[0][i];
  const j = colKeys.findIndex((k) => workSheet[k].v === t);
  if (s && j > -1) {
    workSheet[colKeys[j]].s = s;
  }
});
XLSX.utils.book_append_sheet(book, workSheet, sheetName);
XLSXStyle.writeFile(book, filename, {
  defaultCellStyle /* {
      font: { name: "Verdana", sz: 14, color: {rgb: "FFFF0000"}},
      fill: {fgColor: {rgb: "FF00FF00"}},
      alignment: {vertical: 'center'}
    } */,
});

解决方案1:配置webpack

externals: {
     './cptable': 'var cptable',
},

Umi在config.ts中配置。

解决方案2:删除两个导入 (最佳方案)

import XLSX from "xlsx";
import XLSXStyle from "xlsx-style";

删除之后,上面的代码就能正常使用,编译也不报错了,也不需要进行webpack配置。

因为这两个库不支持ES 6的导出,导出的值是undefined。

解决方案3

使用方案1生成表格时候报错:

意思就是

XLSX为undefined,我去这不是import导入进来了吗,怎么就undefined了。

直接进入XLSX源码查看。

源码里面根本就没有导出XLSX。直接挂在window上面的,什么玩意啊。

修改自己的代码

const data = [
  [
    "demo1",
    "demo2",
    "demo3",
    "demo4",
    "demo5",
    "是否开启(填写注意: 0为否,1为是)",
  ],
  ["1", "2", "3", "4", "5", "0"],
];
const wsWidths = [20, 20, 20, 20, 20, 20];

const book = window.XLSX.utils.book_new(); //没有工作表的空工作簿
const workSheet = window.XLSX.utils.aoa_to_sheet(data);
if (Array.isArray(wsWidths) && wsWidths.length === columnNames[0].length) {
  workSheet["!cols"] = wsWidths.map((width) => ({ wch: width }));
}
if (merge) {
  /**
     *
      合并单元格:
      // s 意为 start ,即开始的单元格
      // r 是 row ,表示行号,从 0 计起
      // c 是 col ,表示列号,从 0 计起
      const merge = [
        // 纵向合并,范围是第1列的行1到行2
        { s: { r: 0, c: 0 }, e: { r: 1, c: 0 } },
        // 纵向合并,范围是第2列的行1到行2
        { s: { r: 0, c: 1 }, e: { r: 1, c: 1 } },
        // 横向合并,范围是第1行的列3到列5
        { s: { r: 0, c: 2 }, e: { r: 0, c: 4 } },
        // 横向合并,范围是第1行的列6到列11
        { s: { r: 0, c: 5 }, e: { r: 0, c: 10 } },
        // 横向合并,范围是第1行的列12到列17
        { s: { r: 0, c: 11 }, e: { r: 0, c: 16 } },
        // 横向合并,范围是第1行的列18到列23
        { s: { r: 0, c: 17 }, e: { r: 0, c: 22 } },
        // 横向合并,范围是第1行的列24到列29
        { s: { r: 0, c: 23 }, e: { r: 0, c: 28 } },
        // 横向合并,范围是第1行的列30到列35
        { s: { r: 0, c: 29 }, e: { r: 0, c: 34 } }
      ];
    */
  workSheet["!merges"] = merge;
}
const colKeys = Object.keys(workSheet).filter((k) => /[A-Z]/.test(k[0]));
styles.forEach((s, i) => {
  const t = columnNames[0][i];
  const j = colKeys.findIndex((k) => workSheet[k].v === t);
  if (s && j > -1) {
    workSheet[colKeys[j]].s = s;
  }
});
 window.XLSX.utils.book_append_sheet(book, workSheet, sheetName);
 window.XLSXStyle.writeFile(book, filename, {
   defaultCellStyle /* {
      font: { name: "Verdana", sz: 14, color: {rgb: "FFFF0000"}},
      fill: {fgColor: {rgb: "FF00FF00"}},
      alignment: {vertical: 'center'}
    } */,
 });

直接使用window点对应的方法。

生成文件内容

2 文件解析


import { Upload } from "antd";
<Upload
  accept=".xlsx"
  fileList={[]}
  beforeUpload={(file) => onBeforeUpload(file)}
>
  <Button>批量上传</Button>
</Upload>;

const isBinary =
  typeof FileReader !== "undefined" &&
  typeof FileReader.prototype !== "undefined" &&
  typeof FileReader.prototype.readAsBinaryString !== "undefined";

let myParseWorker;

function formatData(data) {
  var o = "",
    l = 0,
    w = 10240;
  for (; l < data.byteLength / w; ++l)
    o += String.fromCharCode.apply(
      null,
      new Uint8Array(data.slice(l * w, l * w + w))
    );
  o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)));
  return o;
}
function parseWorker(data) {
  if (!myParseWorker) {
    myParseWorker = new Worker(
      `${
        window.location.protocol +
        "//" +
        window.location.host +
        window.location.pathname
      }xlsx.worker.js`
    );
  }
  return new Promise((resolve, reject) => {
    myParseWorker.onmessage = function (e) {
      switch (e.data.type) {
        case "error":
          reject(e.data.data);
          break;
        case "xlsx":
          return resolve(JSON.parse(e.data.data));
      }
    };
    data = isBinary ? data : btoa(formatData(data));
    myParseWorker.postMessage({ data, binary: isBinary });
  });
}

const onBeforeUpload = async (file) => {
  try {
    const res = new Promise((resolve, reject) => {
      const myFileReader = new FileReader();
      myFileReader.onload = (e) => {
        try {
          parseWorker(e.target.result)
            .then((res) => {
              //if里面可以增加自己的校验方法
              if (true) {
                return resolve(file);
              }
              return reject(e);
            })
            .catch((error) => {
              console.log(error);
              reject(error);
            });
        } catch (error) {
          console.log(error);
          reject(error);
        }
      };
      if (isBinary) {
        myFileReader.readAsBinaryString(file);
      } else {
        myFileReader.readAsArrayBuffer(file);
      }
    });
    return file;
  } catch (error) {
    console.log(error);
  } finally {
  }
};

parseWorker里面then中res

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

cesium-水平测距

cesium测量两点间的距离 <template><div id"cesiumContainer" style"height: 100vh;"></div><div id"toolbar" style"position: fixed;top:20px;left:220px;"><el-breadcrumb><el-breadcrumb-item&…

『运维备忘录』之 Cron 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等只是&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…

Logback学习

logback 1、logback介绍 Logback是由log4j创始人设计的另一个开源日志组件&#xff0c;性能比log4j要好。 lockback优点&#xff1a; 内核重写、测试充分、初始化内存加载更小&#xff0c;这一切让logback性能和log4j相比有诸多倍的提升。logback非常自然地直接实现了slf4j…

CSS的元素显示模式

一&#xff0c;什么是元素显示模式 元素显示模式是指元素以什么方式显示&#xff0c; 作用&#xff1a;了解不同类型的标签可以更好的布局网页。 HTML元素一般分为块元素和行内元素。 1.1块元素 常见的块元素有&#xff1a;<p><ul><ol><li>,<di…

OJ_成绩排序2

题干 c实现 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<vector> #include<algorithm> using namespace std;struct student {char name[16];int score;int seq; };bool comparefromhightolow(student a, student b) {if (a.score > b.…

4通过干扰 Char 设备为 PRNG 添加后门_Linux_Rootkit.md

Xcellerator 密码学Linux其他逆向工程 文章目录 [Linux Rootkit 第 4 部分&#xff1a;通过干扰 Char 设备为 PRNG 添加后门](https://xcellerator.github.io/posts/linux_rootkits_04/)Linux 中的字符设备字符设备的读取例程编写 Rootkit我们能去哪里呢&#xff1f; Linux Ro…

c#string方法对比

字符串的截取匹配操作在开发中非常常见&#xff0c;比如下面这个示例&#xff1a;我要匹配查找出来字符串数组中以“abc”开头的字符串并打印&#xff0c;我下面分别用了两种方式实现&#xff0c;代码如下&#xff1a; using System; namespace ConsoleApp23{ class Progra…

iOS应用提交上架的最新流程

摘要 本篇博客介绍了iOS应用程序上架的最新流程。包括上架基本需求资料、证书的创建和使用、测试设备的添加、描述文件的创建、打包、审核等步骤。 引言 在开发完iOS应用程序后&#xff0c;我们需要将其提交到App Store上架。然而&#xff0c;随着技术的不断发展&#xff0c;…

【数据结构】实现顺序表

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解顺序表&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 一.概念及结构二.接口实现2.1 创建顺序表结构体2.2 初始化顺序表2.3 销毁顺序表2.4 打印顺序表…

力扣面试150 只出现一次的数字Ⅱ 哈希 统计数位 DFA有穷自动机

Problem: 137. 只出现一次的数字 II 文章目录 思路&#x1f496; 哈希&#x1f496; 位数统计&#x1f496; DFA 状态机 思路 &#x1f468;‍&#x1f3eb; 参考 &#x1f496; 哈希 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) cl…

从领域外到领域内:LLM在Text-to-SQL任务中的演进之路

导语 本文介绍了ODIS框架&#xff0c;这是一种新颖的Text-to-SQL方法&#xff0c;它结合了领域外示例和合成生成的领域内示例&#xff0c;以提升大型语言模型在In-context Learning中的性能。 标题&#xff1a;Selective Demonstrations for Cross-domain Text-to-SQL会议&am…

深度学习系列57: 清华大模型MiniCPM上手

MiniCPM 是面壁智能与清华大学自然语言处理实验室共同开源的系列端侧大模型&#xff0c;主体语言模型 MiniCPM-2B 仅有 24亿&#xff08;2.4B&#xff09;的非词嵌入参数量 1. 上手对比测试 mps比cpu大概快了9倍左右。 也可以在modelspore上测试&#xff1a;

XUbuntu22.04之如何创建、切换多个工作区(二百零九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

《最新出炉》系列初窥篇-Python+Playwright自动化测试-13-playwright操作iframe-下篇

1.简介 通过前边两篇的学习&#xff0c;想必大家已经对iframe有了一定的认识和了解&#xff0c;今天这一篇主要是对iframe做一个总结&#xff0c;主要从iframe的操作&#xff08;输入框、点击等等&#xff09;和定位两个方面进行总结。 2.iframe是什么&#xff1f; iframe 简…

【Simulink系列】——动态系统仿真 之 离散系统线性离散系统

一、离散系统定义 离散系统是指系统的输入与输出仅在离散的时间上取值&#xff0c;而且离散的时间具有相同的时间间隔。满足下列条件&#xff1a; ①系统&#xff08;的输入输出&#xff09;每隔固定时间间隔才更新一次。固定时间间隔称为采样时间。 ②系统的输出依赖当前的…

python+flask人口普查数据的应用研究及实现django

作为一款人口普查数据的应用研究及实现&#xff0c;面向的是大多数学者&#xff0c;软件的界面设计简洁清晰&#xff0c;用户可轻松掌握使用技巧。在调查之后&#xff0c;获得用户以下需求&#xff1a; &#xff08;1&#xff09;用户注册登录后&#xff0c;可进入系统解锁更多…

C语言第十八弹---指针(二)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 指针 1、const修饰指针 1.1、const修饰变量 1.2、const修饰指针变量 2、指针运算 2.1、指针- 整数 2.2、指针-指针 2.3、指针的关系运算 3、野指针 3.1、…

【数据结构】----先来聊聊【排序】(先导片)

作为一名对技术充满热情的学习者&#xff0c;我一直以来都深刻地体会到知识的广度和深度。在这个不断演变的数字时代&#xff0c;我远非专家&#xff0c;而是一位不断追求进步的旅行者。通过这篇博客&#xff0c;我想分享我在某个领域的学习经验&#xff0c;与大家共同探讨、共…

Vite+Vue3使用Vue-i18n笔记

一、下载依赖 vue-i18n yarn add vue-i18n创建存放语言文件的目录 以及配置文件的配置 我是在src/lang 新建index.ts、cn.ts、en.ts以及test文件夹其中再分别新建cn.ts以及en.ts /lang/index.ts 用于导出vue-i18n需要的配置对象 import en from "./en.ts"; import…

C#验证字符串是否包含汉字:用正则表达式 vs 用ASCII码 vs 用汉字的 Unicode 编码

目录 一、使用的方法 1.使用正则表达式验证字符串 2.使用正则表达式验证字符 3.用ASCII码判断 4.用汉字的 Unicode 编码范围判断 二、实例 1.源码 2.生成效果 验证一个字符串是否是纯汉字或者包含有汉字的前提&#xff0c;是VS编辑器的默认编码格式设置为&#xff1a;选…