前端获取excel表格数据并在浏览器展示

插件地址:Installation – Univer

本人是在使用react时产生这个需求的  所以示范代码使用react

使用其他框架的可以提取关键代码实现

1、安装插件

安装Univer

使用npm

npm install @univerjs/core @univerjs/design @univerjs/docs @univerjs/docs-ui @univerjs/engine-formula @univerjs/engine-render @univerjs/sheets @univerjs/sheets-formula @univerjs/sheets-ui @univerjs/ui

使用pnpm

pnpm add @univerjs/core @univerjs/design @univerjs/docs @univerjs/docs-ui @univerjs/engine-formula @univerjs/engine-render @univerjs/sheets @univerjs/sheets-formula @univerjs/sheets-ui @univerjs/ui

安装xlsx

npm i xlsx

2、引入插件和实例化插件

你需要在项目中引入 Univer 的样式文件、语言包,以及一些必要的插件:

import "@univerjs/design/lib/index.css";
import "@univerjs/ui/lib/index.css";
import "@univerjs/docs-ui/lib/index.css";
import "@univerjs/sheets-ui/lib/index.css";
import "@univerjs/sheets-formula/lib/index.css";

import { LocaleType, Tools, Univer, UniverInstanceType } from "@univerjs/core";
import { defaultTheme } from "@univerjs/design";

import { UniverFormulaEnginePlugin } from "@univerjs/engine-formula";
import { UniverRenderEnginePlugin } from "@univerjs/engine-render";

import { UniverUIPlugin } from "@univerjs/ui";

import { UniverDocsPlugin } from "@univerjs/docs";
import { UniverDocsUIPlugin } from "@univerjs/docs-ui";

import { UniverSheetsPlugin } from "@univerjs/sheets";
import { UniverSheetsFormulaPlugin } from "@univerjs/sheets-formula";
import { UniverSheetsUIPlugin } from "@univerjs/sheets-ui";

import DesignZhCN from "@univerjs/design/locale/zh-CN";
import UIZhCN from "@univerjs/ui/locale/zh-CN";
import DocsUIZhCN from "@univerjs/docs-ui/locale/zh-CN";
import SheetsZhCN from "@univerjs/sheets/locale/zh-CN";
import SheetsUIZhCN from "@univerjs/sheets-ui/locale/zh-CN";

然后创建一个 Univer 实例,并注册这些插件:

const univer = new Univer({
  theme: defaultTheme,
  locale: LocaleType.ZH_CN,
  locales: {
    [LocaleType.ZH_CN]: Tools.deepMerge(
      SheetsZhCN,
      DocsUIZhCN,
      SheetsUIZhCN,
      UIZhCN,
      DesignZhCN,
    ),
  },
});
 
univer.registerPlugin(UniverRenderEnginePlugin);
univer.registerPlugin(UniverFormulaEnginePlugin);
 
univer.registerPlugin(UniverUIPlugin, {
  container: 'app',
});
 
univer.registerPlugin(UniverDocsPlugin, {
  hasScroll: false,
});
univer.registerPlugin(UniverDocsUIPlugin);
 
univer.registerPlugin(UniverSheetsPlugin);
univer.registerPlugin(UniverSheetsUIPlugin);
univer.registerPlugin(UniverSheetsFormulaPlugin);
 
univer.createUnit(UniverInstanceType.UNIVER_SHEET, {});

 要加载数据还需这个包 @univerjs/facade

npm i @univerjs/facade
import { FUniver } from "@univerjs/facade";
 
const univerAPI = FUniver.newAPI(univer);

3、获取数据源

上传本地文件

const App = () => {
    const handleFileUpload = (e) => {
        const file = e.target.files[0];
        const reader = new FileReader();

        reader.onload = (event) => {
          const data = new Uint8Array(event.target.result);
          const workbook = XLSX.read(data, { type: "array" }); // 数据源
        };
    };

    return <>
        <input type="file" onChange={handleFileUpload} />
    </>
}

根据接口获取

const App = () => {
    const fetchExcelData = async () => {
        try {
          const response = await axios("http://xxx.xxx.xxx", {
            method: "get",
            responseType: "arraybuffer",
            headers: {
              Authorization: "bearer xxx", // 添加你的认证令牌
            },
          });

          const data = new Uint8Array(response.data);
          const workbook = XLSX.read(data, { type: "array" }); // 数据源
        } catch (error) {
          console.error("Failed to fetch Excel data:", error);
        }
      };

    return <></>
}

4、处理成插件所需的数据格式

数据格式定义:Interface: IWorkbookData – Univer

workbook // 数据源 
 const convertWorkbookToJson = (workbook) => {
    const sheets = {};
    const sheetOrder = [];

    workbook.SheetNames.forEach((sheetName, sheetIndex) => {
      const worksheet = workbook.Sheets[sheetName];
      const jsonSheet = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
      console.log(jsonSheet);
      const cellData = {};
      let maxColumnCount = 0;
      jsonSheet.forEach((row, rowIndex) => {
        row.forEach((cell, colIndex) => {
          if (cell !== null && cell !== undefined && cell !== "") {
            if (!cellData[rowIndex]) {
              cellData[rowIndex] = [];
            }
            cellData[rowIndex][colIndex] = { v: cell };
            if (colIndex + 1 > maxColumnCount) {
              maxColumnCount = colIndex + 1;
            }
          }
        });
      });

      const sheetId = `sheet_${sheetIndex}`;
      sheets[sheetId] = {
        id: sheetId,
        name: sheetName,
        rowCount: jsonSheet.length,  // 多少行
        columnCount: maxColumnCount, // 多少列
        zoomRatio: 1,
        defaultColumnWidth: 73,
        defaultRowHeight: 23,
        cellData: cellData, // 每个单元格的数据
        showGridlines: 1,
        rowHeader: {
          width: 40,
          hidden: 0,
        },
        columnHeader: {
          height: 20,
          hidden: 0,
        },
      };

      sheetOrder.push(sheetId);
    });

    return {
      id: "workbook",
      sheetOrder: sheetOrder,
      locale: "zhCN",
      sheets: sheets,
    };
  };

5、在获取数据源后渲染到界面上(完整代码)

渲染效果界面

import "@univerjs/design/lib/index.css";
import "@univerjs/ui/lib/index.css";
import "@univerjs/docs-ui/lib/index.css";
import "@univerjs/sheets-ui/lib/index.css";
import "@univerjs/sheets-formula/lib/index.css";

import { LocaleType, Tools, Univer, UniverInstanceType } from "@univerjs/core";
import { defaultTheme } from "@univerjs/design";

import { UniverFormulaEnginePlugin } from "@univerjs/engine-formula";
import { UniverRenderEnginePlugin } from "@univerjs/engine-render";

import { UniverUIPlugin } from "@univerjs/ui";

import { UniverDocsPlugin } from "@univerjs/docs";
import { UniverDocsUIPlugin } from "@univerjs/docs-ui";

import { UniverSheetsPlugin } from "@univerjs/sheets";
import { UniverSheetsFormulaPlugin } from "@univerjs/sheets-formula";
import { UniverSheetsUIPlugin } from "@univerjs/sheets-ui";

import DesignZhCN from "@univerjs/design/locale/zh-CN";
import UIZhCN from "@univerjs/ui/locale/zh-CN";
import DocsUIZhCN from "@univerjs/docs-ui/locale/zh-CN";
import SheetsZhCN from "@univerjs/sheets/locale/zh-CN";
import SheetsUIZhCN from "@univerjs/sheets-ui/locale/zh-CN";

import { FUniver } from "@univerjs/facade";
import { useEffect, useRef, useState } from "react";
import * as XLSX from "xlsx";

const App = () => {
  const univerAPI = useRef();
  const univer = useRef();

  useEffect(() => {
    // fetchExcelData(); // 接口获取删除此行注释  本地上传点击上传按钮
  }, []);


  const init = () => {
    univer.current = new Univer({
      theme: defaultTheme,
      locale: LocaleType.ZH_CN,
      locales: {
        [LocaleType.ZH_CN]: Tools.deepMerge(
          SheetsZhCN,
          DocsUIZhCN,
          SheetsUIZhCN,
          UIZhCN,
          DesignZhCN
        ),
      },
    });

    univer.current.registerPlugin(UniverRenderEnginePlugin);
    univer.current.registerPlugin(UniverFormulaEnginePlugin);

    univer.current.registerPlugin(UniverUIPlugin, {
      container: "excel2",
    });

    univer.current.registerPlugin(UniverDocsPlugin, {
      hasScroll: false,
    });
    univer.current.registerPlugin(UniverDocsUIPlugin);

    univer.current.registerPlugin(UniverSheetsPlugin);
    univer.current.registerPlugin(UniverSheetsUIPlugin);
    univer.current.registerPlugin(UniverSheetsFormulaPlugin);

    univerAPI.current = FUniver.newAPI(univer.current);

    // 创建一个空白的表格可删除以下代码注释 并在useEffect中执行init();

    // univer.current.createUnit(UniverInstanceType.UNIVER_SHEET, {
    //   id: "gyI0JO",
    //   sheetOrder: ["RSfWjJFv4opmE1JaiRj80"],
    //   name: "",
    //   appVersion: "0.1.11",
    //   locale: "zhCN",
    //   styles: {},
    //   sheets: {
    //     RSfWjJFv4opmE1JaiRj80: {
    //       id: "RSfWjJFv4opmE1JaiRj80",
    //       name: "测试",
    //       tabColor: "",
    //       hidden: 0,
    //       rowCount: 20,
    //       columnCount: 10,
    //       zoomRatio: 1,
    //       freeze: {
    //         startRow: -1,
    //         startColumn: -1,
    //         ySplit: 0,
    //         xSplit: 0,
    //       },
    //       scrollTop: 0,
    //       scrollLeft: 0,
    //       defaultColumnWidth: 73,
    //       defaultRowHeight: 23,
    //       mergeData: [],
    //       cellData: {
    //         0: [
    //           {
    //             v: "123",
    //           },
    //           {
    //             v: "222",
    //           },
    //         ],
    //       },
    //       rowData: {
    //         0: {
    //           h: 105,
    //           hd: 0,
    //         },
    //       },
    //       columnData: {
    //         0: {
    //           w: 105,
    //           hd: 0,
    //         },
    //         1: {
    //           w: 100,
    //           hd: 0,
    //         },
    //         2: {
    //           w: 125,
    //           hd: 0,
    //         },
    //         3: {
    //           w: 125,
    //           hd: 0,
    //         },
    //         4: {
    //           w: 125,
    //           hd: 0,
    //         },
    //         5: {
    //           w: 125,
    //           hd: 0,
    //         },
    //         6: {
    //           w: 125,
    //           hd: 0,
    //         },
    //         7: {
    //           w: 125,
    //           hd: 0,
    //         },
    //         8: {
    //           w: 125,
    //           hd: 0,
    //         },
    //         9: {
    //           w: 125,
    //           hd: 0,
    //         },
    //       },
    //       showGridlines: 1,
    //       rowHeader: {
    //         width: 40,
    //         hidden: 0,
    //       },
    //       columnHeader: {
    //         height: 20,
    //         hidden: 0,
    //       },
    //       selections: ["B2"],
    //       rightToLeft: 0,
    //     },
    //   },
    //   resources: [
    //     {
    //       name: "SHEET_DEFINED_NAME_PLUGIN",
    //       data: "",
    //     },
    //   ],
    // });
  };

   // 点击上传按钮获取数据
  const handleFileUpload = (e) => {
    const file = e.target.files[0];
    const reader = new FileReader();

    reader.onload = (event) => {
      const data = new Uint8Array(event.target.result);
      const workbook = XLSX.read(data, { type: "array" }); // 数据源
      const jsonWorkbook = convertWorkbookToJson(workbook);

      univer.current.createUnit(UniverInstanceType.UNIVER_SHEET, jsonWorkbook) // 输入数据生成表格
    };
  };

    // 接口获取
  const fetchExcelData = async () => {
    try {
      const response = await axios("http://xxx.xxx.xxx", {
        method: "get",
        responseType: "arraybuffer", // 确保以数组缓冲区的形式获取二进制数据
        headers: {
          Authorization: "bearer xxx", // 添加你的认证令牌
        },
      });

      const data = new Uint8Array(response.data);
      const workbook = XLSX.read(data, { type: "array" }); // 数据源
      const jsonWorkbook = convertWorkbookToJson(workbook);

      univer.current.createUnit(UniverInstanceType.UNIVER_SHEET, jsonWorkbook) // 输入数据生成表格
    } catch (error) {
      console.error("Failed to fetch Excel data:", error);
    }
  };

  const convertWorkbookToJson = (workbook) => {
    const sheets = {};
    const sheetOrder = [];

    workbook.SheetNames.forEach((sheetName, sheetIndex) => {
      const worksheet = workbook.Sheets[sheetName];
      const jsonSheet = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
      console.log(jsonSheet);
      const cellData = {};
      let maxColumnCount = 0;
      jsonSheet.forEach((row, rowIndex) => {
        row.forEach((cell, colIndex) => {
          if (cell !== null && cell !== undefined && cell !== "") {
            if (!cellData[rowIndex]) {
              cellData[rowIndex] = [];
            }
            cellData[rowIndex][colIndex] = { v: cell };
            if (colIndex + 1 > maxColumnCount) {
              maxColumnCount = colIndex + 1;
            }
          }
        });
      });

      const sheetId = `sheet_${sheetIndex}`;
      sheets[sheetId] = {
        id: sheetId,
        name: sheetName,
        rowCount: jsonSheet.length,
        columnCount: maxColumnCount,
        zoomRatio: 1,
        defaultColumnWidth: 73,
        defaultRowHeight: 23,
        mergeData: mergeData,
        cellData: cellData,
        showGridlines: 1,
        rowHeader: {
          width: 40,
          hidden: 0,
        },
        columnHeader: {
          height: 20,
          hidden: 0,
        },
      };

      sheetOrder.push(sheetId);
    });

    return {
      id: "workbook",
      sheetOrder: sheetOrder,
      locale: "zhCN",
      sheets: sheets,
    };
  };
  return (
    <>
      {/* 表格容器 */}
      <div id="excel2" style={{ width: "1000px", height: "800px" }}></div>
      {/* 上传按钮 */}
      <input type="file" onChange={handleFileUpload} />
    </>
  );
};

export default App;

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值