符生 發表於 2026-1-13 09:15:52

微信小程序中如何使用xlsx(xlsx.mini.min.js)实现Excel导入导出功能

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">一、简介</a></li><li><a href="#_label1">二、准备工作</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_0">1. 下载 xlsx.mini.min.js</a></li><li><a href="#_lab2_1_1">2. 引入库文件</a></li></ul><li><a href="#_label2">三、导出 Excel</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_2">3.1 基本流程</a></li><li><a href="#_lab2_2_3">3.2 完整代码示例</a></li></ul><li><a href="#_label3">四、导入 Excel</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_4">4.1 基本流程</a></li><li><a href="#_lab2_3_5">4.2 完整代码示例</a></li><li><a href="#_lab2_3_6">4.3 重复数据检测示例</a></li></ul><li><a href="#_label4">五、常用 API 说明</a></li><ul class="second_class_ul"><li><a href="#_lab2_4_7">5.1 核心方法</a></li><li><a href="#_lab2_4_8">5.2 工作表属性设置</a></li><li><a href="#_lab2_4_9">5.3 xlsx.write() 选项</a></li><li><a href="#_lab2_4_10">5.4 sheet_to_json() 选项</a></li></ul><li><a href="#_label5">六、注意事项</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>一、简介</h2>
<p><code>xlsx.mini.min.js</code> 是 SheetJS 的迷你版本,专门为小程序等轻量级环境设计。本文基于微信小程序环境,详细介绍如何使用该库实现 Excel 文件的导入和导出功能。</p>
<p class="maodian"><a name="_label1"></a></p><h2>二、准备工作</h2>
<p class="maodian"><a name="_lab2_1_0"></a></p><h3>1. 下载 xlsx.mini.min.js</h3>
<ul><li>访问 SheetJS 官方仓库:https://git.sheetjs.com/sheetjs/sheetjs</li><li>进入 <code>dist</code> 目录,下载 <code>xlsx.mini.min.js</code> 文件,可以只单独下载这个文件就行</li><li>将文件放置到小程序项目的 <code>libs</code> 目录下</li></ul>
<p class="maodian"><a name="_lab2_1_1"></a></p><h3>2. 引入库文件</h3>
<p>在需要使用 Excel 功能的页面或组件中引入:</p>
<div class="jb51code"><pre class="brush:js;">const xlsx = require("../../libs/xlsx.mini.min")
</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>三、导出 Excel</h2>
<p class="maodian"><a name="_lab2_2_2"></a></p><h3>3.1 基本流程</h3>
<ol><li><strong>构建数据数组</strong>:将数据组织成二维数组格式</li><li><strong>创建工作表</strong>:使用 <code>xlsx.utils.aoa_to_sheet()</code> 将数组转换为工作表</li><li><strong>设置列宽</strong>(可选):通过 <code>ws[&#39;!cols&#39;]</code> 设置列宽</li><li><strong>创建工作簿</strong>:使用 <code>xlsx.utils.book_new()</code> 创建新工作簿</li><li><strong>添加工作表</strong>:使用 <code>xlsx.utils.book_append_sheet()</code> 将工作表添加到工作簿</li><li><strong>生成文件</strong>:使用 <code>xlsx.write()</code> 将工作簿转换为 base64 格式</li><li><strong>保存文件</strong>:使用微信小程序的 <code>wx.getFileSystemManager()</code> 保存文件</li></ol>
<p class="maodian"><a name="_lab2_2_3"></a></p><h3>3.2 完整代码示例</h3>
<div class="jb51code"><pre class="brush:js;">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) =&gt; {
    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) =&gt; {
      const sysInfo = wx.getSystemInfoSync()
      
      // PC 端导出
      if (sysInfo.platform.toLowerCase().indexOf('windows') &gt;= 0) {
          wx.saveFileToDisk({
            filePath: filePath,
            success: () =&gt; {
            wx.showToast({
                title: '导出成功',
                icon: 'success'
            })
            },
            fail: () =&gt; {
            wx.showToast({
                title: '导出失败',
                icon: 'none'
            })
            }
          })
      } else {
          // 手机端导出 - 打开文档
          wx.openDocument({
            filePath: filePath,
            showMenu: true,
            success: () =&gt; {
            wx.showToast({
                title: '导出成功',
                icon: 'success'
            })
            },
            fail: () =&gt; {
            wx.showToast({
                title: '导出失败',
                icon: 'none'
            })
            }
          })
      }
      },
      fail: (res) =&gt; {
      if (res.errMsg &amp;&amp; res.errMsg.indexOf('locked') &gt;= 0) {
          wx.showModal({
            title: '提示',
            content: '文档已打开,请先关闭',
          })
      } else {
          wx.showToast({
            title: '导出失败',
            icon: 'none'
          })
      }
      }
    })
} catch (error) {
    console.error('导出 Excel 失败:', error)
    wx.showToast({
      title: '导出失败',
      icon: 'none'
    })
}
}
</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>四、导入 Excel</h2>
<p class="maodian"><a name="_lab2_3_4"></a></p><h3>4.1 基本流程</h3>
<ol><li><strong>选择文件</strong>:使用 <code>wx.chooseMessageFile()</code> 选择 Excel 文件</li><li><strong>读取文件</strong>:使用 <code>wx.getFileSystemManager().readFile()</code> 读取文件内容(base64 格式)</li><li><strong>解析 Excel</strong>:使用 <code>xlsx.read()</code> 解析文件</li><li><strong>转换为 JSON</strong>:使用 <code>xlsx.utils.sheet_to_json()</code> 将工作表转换为 JSON 数组</li><li><strong>处理数据</strong>:解析 JSON 数据并转换为应用所需格式</li><li><strong>保存数据</strong>:将处理后的数据保存到本地存储</li></ol>
<p class="maodian"><a name="_lab2_3_5"></a></p><h3>4.2 完整代码示例</h3>
<div class="jb51code"><pre class="brush:js;">importFromExcel() {
// 1. 选择文件
wx.chooseMessageFile({
    count: 1,
    type: 'file',
    extension: ['xlsx', 'xls'],
    success: (res) =&gt; {
      const file = res.tempFiles
      if (!file) {
      wx.showToast({
          title: '文件选择失败',
          icon: 'none'
      })
      return
      }

      // 2. 读取文件
      const fs = wx.getFileSystemManager()
      fs.readFile({
      filePath: file.path,
      encoding: 'base64',
      success: (readRes) =&gt; {
          try {
            // 3. 解析 Excel
            const workbook = xlsx.read(readRes.data, { type: 'base64' })
            const firstSheetName = workbook.SheetNames
            const worksheet = workbook.Sheets
            
            // 4. 转换为 JSON 数组(header: 1 表示第一行作为表头)
            const jsonData = xlsx.utils.sheet_to_json(worksheet, {
            header: 1,
            defval: ''
            })

            if (!jsonData || jsonData.length &lt; 2) {
            wx.showToast({
                title: 'Excel 文件格式不正确',
                icon: 'none'
            })
            return
            }

            // 5. 解析表头
            const headers = jsonData
            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 &lt; jsonData.length; i++) {
            const row = jsonData
            if (!row &amp;&amp; !row) {
                continue // 跳过空行
            }

            importedData.push({
                date: row || '',
                allmoney: row || '0',
                uuid: row || 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) =&gt; {
          console.error('读取文件失败:', err)
          wx.showToast({
            title: '读取文件失败',
            icon: 'none'
          })
      }
      })
    },
    fail: (err) =&gt; {
      if (err.errMsg &amp;&amp; err.errMsg.indexOf('cancel') === -1) {
      wx.showToast({
          title: '选择文件失败',
          icon: 'none'
      })
      }
    }
})
}
</pre></div>
<p class="maodian"><a name="_lab2_3_6"></a></p><h3>4.3 重复数据检测示例</h3>
<p>在导入时检测重复数据并提示用户:</p>
<div class="jb51code"><pre class="brush:js;">// 检查是否有重复数据(对比 uuid 字段)
const duplicateUuids = []
importedData.forEach(item =&gt; {
const itemUuid = String(item['uuid'] || '')
const existingIndex = currentData.findIndex((existing) =&gt;
    String(existing['uuid'] || '') === itemUuid
)
if (existingIndex &gt;= 0) {
    duplicateUuids.push(itemUuid)
}
})

// 如果有重复数据,提示用户
if (duplicateUuids.length &gt; 0) {
wx.showModal({
    title: '数据重复',
    content: `检测到 ${duplicateUuids.length} 条重复数据,是否覆盖?`,
    confirmText: '覆盖',
    cancelText: '取消',
    success: (modalRes) =&gt; {
      if (modalRes.confirm) {
      // 执行导入逻辑
      doImport(importedData)
      } else {
      wx.showToast({
          title: '已取消导入',
          icon: 'none'
      })
      }
    }
})
} else {
// 没有重复,直接导入
doImport(importedData)
}
</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>五、常用 API 说明</h2>
<p class="maodian"><a name="_lab2_4_7"></a></p><h3>5.1 核心方法</h3>
<table><thead><tr><th>方法</th><th>说明</th><th>示例</th></tr></thead><tbody><tr><td><code>xlsx.utils.aoa_to_sheet(data)</code></td><td>将二维数组转换为工作表</td><td><code>xlsx.utils.aoa_to_sheet([[&#39;A&#39;, &#39;B&#39;], ])</code></td></tr><tr><td><code>xlsx.utils.book_new()</code></td><td>创建新工作簿</td><td><code>var wb = xlsx.utils.book_new()</code></td></tr><tr><td><code>xlsx.utils.book_append_sheet(wb, ws, name)</code></td><td>将工作表添加到工作簿</td><td><code>xlsx.utils.book_append_sheet(wb, ws, &quot;Sheet1&quot;)</code></td></tr><tr><td><code>xlsx.write(wb, options)</code></td><td>将工作簿转换为指定格式</td><td><code>xlsx.write(wb, {bookType: &quot;xlsx&quot;, type: &#39;base64&#39;})</code></td></tr><tr><td><code>xlsx.read(data, options)</code></td><td>读取 Excel 文件</td><td><code>xlsx.read(base64Data, { type: &#39;base64&#39; })</code></td></tr><tr><td><code>xlsx.utils.sheet_to_json(ws, options)</code></td><td>将工作表转换为 JSON</td><td><code>xlsx.utils.sheet_to_json(ws, { header: 1 })</code></td></tr></tbody></table>
<p class="maodian"><a name="_lab2_4_8"></a></p><h3>5.2 工作表属性设置</h3>
<p><strong>设置列宽:</strong></p>
<div class="jb51code"><pre class="brush:js;">ws['!cols'] = [
{ wch: 15 },// 第一列宽度:15个字符
{ wch: 20 },// 第二列宽度:20个字符
{ wch: 30 }   // 第三列宽度:30个字符
]
</pre></div>
<p><strong>设置行高(可选):</strong></p>
<div class="jb51code"><pre class="brush:js;">ws['!rows'] = [
{ hpt: 20 },// 第一行高度:20磅
{ hpt: 15 }   // 第二行高度:15磅
]
</pre></div>
<p class="maodian"><a name="_lab2_4_9"></a></p><h3>5.3 xlsx.write() 选项</h3>
<div class="jb51code"><pre class="brush:js;">xlsx.write(wb, {
bookType: "xlsx",// 文件类型:xlsx, xls, csv 等
type: 'base64',    // 输出类型:base64, binary, string, buffer
bookSST: true      // 是否使用共享字符串表(可选)
})
</pre></div>
<p class="maodian"><a name="_lab2_4_10"></a></p><h3>5.4 sheet_to_json() 选项</h3>
<div class="jb51code"><pre class="brush:js;">xlsx.utils.sheet_to_json(worksheet, {
header: 1,      // 1: 数组格式,'A': 对象格式(使用列名)
defval: '',       // 默认值(空单元格的值)
raw: false      // false: 自动转换数据类型,true: 保持原始值
})
</pre></div>
<p class="maodian"><a name="_label5"></a></p><h2>六、注意事项</h2>
<ol><li><p><strong>文件大小限制</strong>:微信小程序对文件大小有限制,建议单个 Excel 文件不超过 2MB</p></li><li><p><strong>数据类型</strong>:导入时注意数据类型转换,Excel 中的数字可能被解析为字符串</p></li><li><p><strong>空值处理</strong>:使用 <code>defval</code> 参数设置空单元格的默认值</p></li><li><p><strong>错误处理</strong>:务必添加 try-catch 错误处理,避免程序崩溃</p></li><li><p><strong>平台差异</strong>:PC 端和手机端的文件保存方式不同,需要分别处理</p></li><li><p><strong>文件路径</strong>:使用 <code>wx.env.USER_DATA_PATH</code> 获取用户数据目录</p></li><li><p><strong>列宽单位</strong>:<code>wch</code> 表示字符宽度,不是像素</p></li><li><p><strong>工作表名称</strong>:工作表名称不能包含特殊字符,建议使用中文、英文、数字</p></li></ol>
<p>希望本文能帮助你在微信小程序项目中顺利实现 Excel 导入导出功能!</p>
<p><strong>参考资源:</strong></p>
<ul><li>SheetJS 官方文档:https://docs.sheetjs.com/</li><li>SheetJS GitHub:https://github.com/SheetJS/sheetjs</li></ul>
頁: [1]
查看完整版本: 微信小程序中如何使用xlsx(xlsx.mini.min.js)实现Excel导入导出功能