一、简介
xlsx.mini.min.js 是 SheetJS 的迷你版本,专门为小程序等轻量级环境设计。本文基于微信小程序环境,详细介绍如何使用该库实现 Excel 文件的导入和导出功能。
二、准备工作
1. 下载 xlsx.mini.min.js
- 访问 SheetJS 官方仓库:https://git.sheetjs.com/sheetjs/sheetjs
- 进入
dist目录,下载xlsx.mini.min.js文件,可以只单独下载这个文件就行 - 将文件放置到小程序项目的
libs目录下
2. 引入库文件
在需要使用 Excel 功能的页面或组件中引入:
javascript
const xlsx = require("../../libs/xlsx.mini.min")
三、导出 Excel
3.1 基本流程
- 构建数据数组:将数据组织成二维数组格式
- 创建工作表 :使用
xlsx.utils.aoa_to_sheet()将数组转换为工作表 - 设置列宽 (可选):通过
ws['!cols']设置列宽 - 创建工作簿 :使用
xlsx.utils.book_new()创建新工作簿 - 添加工作表 :使用
xlsx.utils.book_append_sheet()将工作表添加到工作簿 - 生成文件 :使用
xlsx.write()将工作簿转换为 base64 格式 - 保存文件 :使用微信小程序的
wx.getFileSystemManager()保存文件
3.2 完整代码示例
javascript
exportToExcel() {
const { list } = this.data
if (!list || list.length === 0) {
wx.showToast({
title: '暂无数据可导出',
icon: 'none'
})
return
}
// 1. 构建 Excel 数据表(二维数组)
let sheet = []
// 表头
let titles = ['日期', 'XXXX', 'uuid']
sheet.push(titles)
// 数据行
list.forEach((item) => {
let row = [
item['date'] || '',
item['xxxx'] || '0',
item['uuid'] || ''
]
sheet.push(row)
})
try {
// 2. 将数组转换为工作表
var ws = xlsx.utils.aoa_to_sheet(sheet)
// 3. 设置列宽(可选)
const colWidths = [
{ wch: 15 }, // 日期列:15个字符宽度
{ wch: 15 }, // 总资产列:15个字符宽度
{ wch: 30 } // uuid列:30个字符宽度
]
ws['!cols'] = colWidths
// 4. 创建工作簿
var wb = xlsx.utils.book_new()
// 5. 将工作表添加到工作簿(第三个参数是工作表名称)
xlsx.utils.book_append_sheet(wb, ws, "数据记录")
// 6. 将工作簿转换为 base64 格式
var fileData = xlsx.write(wb, {
bookType: "xlsx",
type: 'base64'
})
// 7. 保存文件
let filePath = `${wx.env.USER_DATA_PATH}/数据记录.xlsx`
const fs = wx.getFileSystemManager()
fs.writeFile({
filePath: filePath,
data: fileData,
encoding: 'base64',
success: (res) => {
const sysInfo = wx.getSystemInfoSync()
// PC 端导出
if (sysInfo.platform.toLowerCase().indexOf('windows') >= 0) {
wx.saveFileToDisk({
filePath: filePath,
success: () => {
wx.showToast({
title: '导出成功',
icon: 'success'
})
},
fail: () => {
wx.showToast({
title: '导出失败',
icon: 'none'
})
}
})
} else {
// 手机端导出 - 打开文档
wx.openDocument({
filePath: filePath,
showMenu: true,
success: () => {
wx.showToast({
title: '导出成功',
icon: 'success'
})
},
fail: () => {
wx.showToast({
title: '导出失败',
icon: 'none'
})
}
})
}
},
fail: (res) => {
if (res.errMsg && res.errMsg.indexOf('locked') >= 0) {
wx.showModal({
title: '提示',
content: '文档已打开,请先关闭',
})
} else {
wx.showToast({
title: '导出失败',
icon: 'none'
})
}
}
})
} catch (error) {
console.error('导出 Excel 失败:', error)
wx.showToast({
title: '导出失败',
icon: 'none'
})
}
}
四、导入 Excel
4.1 基本流程
- 选择文件 :使用
wx.chooseMessageFile()选择 Excel 文件 - 读取文件 :使用
wx.getFileSystemManager().readFile()读取文件内容(base64 格式) - 解析 Excel :使用
xlsx.read()解析文件 - 转换为 JSON :使用
xlsx.utils.sheet_to_json()将工作表转换为 JSON 数组 - 处理数据:解析 JSON 数据并转换为应用所需格式
- 保存数据:将处理后的数据保存到本地存储
4.2 完整代码示例
javascript
importFromExcel() {
// 1. 选择文件
wx.chooseMessageFile({
count: 1,
type: 'file',
extension: ['xlsx', 'xls'],
success: (res) => {
const file = res.tempFiles[0]
if (!file) {
wx.showToast({
title: '文件选择失败',
icon: 'none'
})
return
}
// 2. 读取文件
const fs = wx.getFileSystemManager()
fs.readFile({
filePath: file.path,
encoding: 'base64',
success: (readRes) => {
try {
// 3. 解析 Excel
const workbook = xlsx.read(readRes.data, { type: 'base64' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
// 4. 转换为 JSON 数组(header: 1 表示第一行作为表头)
const jsonData = xlsx.utils.sheet_to_json(worksheet, {
header: 1,
defval: ''
})
if (!jsonData || jsonData.length < 2) {
wx.showToast({
title: 'Excel 文件格式不正确',
icon: 'none'
})
return
}
// 5. 解析表头
const headers = jsonData[0]
const dateIndex = headers.indexOf('日期')
const moneyIndex = headers.indexOf('总资产(元)')
const uuidIndex = headers.indexOf('uuid')
if (dateIndex === -1 || moneyIndex === -1) {
wx.showToast({
title: 'Excel 文件缺少必要列',
icon: 'none'
})
return
}
// 6. 处理数据
const importedData = []
for (let i = 1; i < jsonData.length; i++) {
const row = jsonData[i]
if (!row[dateIndex] && !row[moneyIndex]) {
continue // 跳过空行
}
importedData.push({
date: row[dateIndex] || '',
allmoney: row[moneyIndex] || '0',
uuid: row[uuidIndex] || String((new Date()).getTime() + i)
})
}
if (importedData.length === 0) {
wx.showToast({
title: '没有有效数据可导入',
icon: 'none'
})
return
}
// 7. 保存数据
const currentData = wx.getStorageSync("data") ? JSON.parse(wx.getStorageSync("data")) : []
const mergedData = [...currentData, ...importedData]
wx.setStorageSync("data", JSON.stringify(mergedData))
wx.showToast({
title: `成功导入 ${importedData.length} 条记录`,
icon: 'success'
})
} catch (error) {
console.error('导入 Excel 失败:', error)
wx.showToast({
title: '导入失败,请检查文件格式',
icon: 'none'
})
}
},
fail: (err) => {
console.error('读取文件失败:', err)
wx.showToast({
title: '读取文件失败',
icon: 'none'
})
}
})
},
fail: (err) => {
if (err.errMsg && err.errMsg.indexOf('cancel') === -1) {
wx.showToast({
title: '选择文件失败',
icon: 'none'
})
}
}
})
}
4.3 重复数据检测示例
在导入时检测重复数据并提示用户:
javascript
// 检查是否有重复数据(对比 uuid 字段)
const duplicateUuids = []
importedData.forEach(item => {
const itemUuid = String(item['uuid'] || '')
const existingIndex = currentData.findIndex((existing) =>
String(existing['uuid'] || '') === itemUuid
)
if (existingIndex >= 0) {
duplicateUuids.push(itemUuid)
}
})
// 如果有重复数据,提示用户
if (duplicateUuids.length > 0) {
wx.showModal({
title: '数据重复',
content: `检测到 ${duplicateUuids.length} 条重复数据,是否覆盖?`,
confirmText: '覆盖',
cancelText: '取消',
success: (modalRes) => {
if (modalRes.confirm) {
// 执行导入逻辑
doImport(importedData)
} else {
wx.showToast({
title: '已取消导入',
icon: 'none'
})
}
}
})
} else {
// 没有重复,直接导入
doImport(importedData)
}
五、常用 API 说明
5.1 核心方法
| 方法 | 说明 | 示例 |
|---|---|---|
xlsx.utils.aoa_to_sheet(data) |
将二维数组转换为工作表 | xlsx.utils.aoa_to_sheet([['A', 'B'], [1, 2]]) |
xlsx.utils.book_new() |
创建新工作簿 | var wb = xlsx.utils.book_new() |
xlsx.utils.book_append_sheet(wb, ws, name) |
将工作表添加到工作簿 | xlsx.utils.book_append_sheet(wb, ws, "Sheet1") |
xlsx.write(wb, options) |
将工作簿转换为指定格式 | xlsx.write(wb, {bookType: "xlsx", type: 'base64'}) |
xlsx.read(data, options) |
读取 Excel 文件 | xlsx.read(base64Data, { type: 'base64' }) |
xlsx.utils.sheet_to_json(ws, options) |
将工作表转换为 JSON | xlsx.utils.sheet_to_json(ws, { header: 1 }) |
5.2 工作表属性设置
设置列宽:
javascript
ws['!cols'] = [
{ wch: 15 }, // 第一列宽度:15个字符
{ wch: 20 }, // 第二列宽度:20个字符
{ wch: 30 } // 第三列宽度:30个字符
]
设置行高(可选):
javascript
ws['!rows'] = [
{ hpt: 20 }, // 第一行高度:20磅
{ hpt: 15 } // 第二行高度:15磅
]
5.3 xlsx.write() 选项
javascript
xlsx.write(wb, {
bookType: "xlsx", // 文件类型:xlsx, xls, csv 等
type: 'base64', // 输出类型:base64, binary, string, buffer
bookSST: true // 是否使用共享字符串表(可选)
})
5.4 sheet_to_json() 选项
javascript
xlsx.utils.sheet_to_json(worksheet, {
header: 1, // 1: 数组格式,'A': 对象格式(使用列名)
defval: '', // 默认值(空单元格的值)
raw: false // false: 自动转换数据类型,true: 保持原始值
})
六、注意事项
-
文件大小限制:微信小程序对文件大小有限制,建议单个 Excel 文件不超过 2MB
-
数据类型:导入时注意数据类型转换,Excel 中的数字可能被解析为字符串
-
空值处理 :使用
defval参数设置空单元格的默认值 -
错误处理:务必添加 try-catch 错误处理,避免程序崩溃
-
平台差异:PC 端和手机端的文件保存方式不同,需要分别处理
-
文件路径 :使用
wx.env.USER_DATA_PATH获取用户数据目录 -
列宽单位 :
wch表示字符宽度,不是像素 -
工作表名称:工作表名称不能包含特殊字符,建议使用中文、英文、数字
希望本文能帮助你在微信小程序项目中顺利实现 Excel 导入导出功能!
参考资源:
- SheetJS 官方文档:https://docs.sheetjs.com/
- SheetJS GitHub:https://github.com/SheetJS/sheetjs