基于Vue3与Luckysheet实现Excel文件在线预览方案
通过npm方式集成Luckysheet组件,版本配置为"luckysheet": "^2.1.13"与"xlsx": "^0.18.5"。安装命令如下:
npm install luckysheet xlsx
在项目入口文件中添加资源引用:
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Luckysheet资源加载 -->
<link href="https://cdn.jsdelivr.net/npm/luckysheet@2.1.13/dist/css/luckysheet.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/luckysheet@2.1.13/dist/plugins/css/pluginsCss.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/luckysheet@2.1.13/dist/plugins/plugins.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/luckysheet@2.1.13/dist/assets/iconfont/iconfont.css" rel="stylesheet">
<title>Excel在线预览</title>
</head>
<body>
<div id="app">
<input type="file" @change="onFileSelect" accept=".xlsx,.xls,.csv" />
<div id="sheet-container" style="width:100%;height:600px;"></div>
</div>
<script src="/node_modules/luckysheet/dist/plugins/js/plugin.js"></script>
<script src="/node_modules/luckysheet/dist/luckysheet.umd.js"></script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
文件上传处理组件:
<template>
<div>
<input type="file" @change="onFileSelect" accept=".xlsx,.xls,.csv" />
<div id="sheet-container" style="width:100%;height:600px;"></div>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
import * as XLSX from 'xlsx';
let sheetEditor = null;
const onFileSelect = async (e) => {
const file = e.target.files[0];
if (!file) return;
// 清理旧实例
if (sheetEditor) {
try {
sheetEditor.destroy();
} catch (err) {
console.error('销毁实例异常:', err);
}
}
const reader = new FileReader();
reader.onload = (evt) => {
try {
parseData(evt.target.result, file.name);
} catch (err) {
console.error('数据解析失败:', err);
}
};
reader.onerror = () => {
console.error('文件读取异常:', reader.error);
};
// 按文件类型选择读取方式
if (file.name.endsWith('.csv')) {
reader.readAsText(file, 'UTF-8');
} else {
reader.readAsArrayBuffer(file);
}
};
const parseData = (data, filename) => {
let workbook;
if (filename.endsWith('.csv')) {
const csvContent = XLSX.utils.aoa_to_sheet(data);
const csvStr = XLSX.utils.sheet_to_csv(csvContent);
workbook = XLSX.read(csvStr, {type: 'string'});
} else {
workbook = XLSX.read(data, {type: 'array'});
}
const config = {
container: 'sheet-container',
title: filename,
data: [],
lang: 'zh',
showtoolbar: true,
allowEdit: false,
showinfobar: false,
showformula: false,
showcontextmenu: false,
showbottombar: false
};
workbook.SheetNames.forEach(sheetName => {
const sheet = workbook.Sheets[sheetName];
const rows = XLSX.utils.sheet_to_json(sheet, {header:1});
config.data.push({
name: sheetName,
celldata: formatCellData(rows)
});
});
try {
sheetEditor = window.luckysheet.create(config);
} catch (err) {
console.error('初始化异常:', err);
}
};
const formatCellData = (data) => {
return data.flatMap((row, r) =>
row.map((cell, c) => ({
r: r,
c: c,
v: cell
}))
);
};
onMounted(() => {
// 初始化时可添加默认数据
});
</script>

