如何使用JavaScript在服务端读取受密码保护的XLSX文件
问题根因
你当前使用的开源版SheetJS(XLSX类库)本身未提供密码保护XLSX文件的解密能力,仅付费专业版支持该功能,因此即使传入password参数也无法正常解析加密文件,会抛出对应报错。
可行解决方案
方案1:使用exceljs库完成读取(支持服务端Node.js+浏览器端)
exceljs原生支持加密XLSX文件的读写,服务端和前端都可以正常运行,示例代码如下:
服务端Node.js示例
const ExcelJS = require('exceljs'); const fs = require('fs'); async function readProtectedXlsx(filePath, password) { const workbook = new ExcelJS.Workbook(); await workbook.xlsx.readFile(filePath, { password: password }); // 读取第一个工作表 const worksheet = workbook.getWorksheet(1); // 转换为JSON格式,可根据需求调整遍历逻辑 const jsonData = []; worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => { jsonData.push(row.values); }); return jsonData; }
前端浏览器端示例
对应你之前的前端选择文件的场景,可以替换为如下代码:
<html> <label for="file-selector">Select a file</label> <input type="file" id ="file-selector" required=""> </html> <!-- 提前将exceljs的静态资源放到本地项目中引入即可 --> <script src="你的项目本地exceljs资源路径"></script> <script> const fileSelector = document.getElementById("file-selector"); fileSelector.addEventListener('change', async () => { const file = fileSelector.files[0]; const workbook = new ExcelJS.Workbook(); await workbook.xlsx.load(file, { password: "你的文件密码" }); const worksheet = workbook.getWorksheet(1); const jsonData = []; worksheet.eachRow({ includeEmpty: false }, (row) => { jsonData.push(row.values); }); console.log(jsonData); }) </script>
方案2:先解密文件流再使用原有SheetJS库解析
适合不想修改原有SheetJS解析逻辑的场景,可以使用officecrypto-tool库先解密加密的XLSX文件流,再将解密后的流传给原有逻辑解析:
- 先安装依赖:
npm install officecrypto-tool xlsx - 服务端示例代码:
const fs = require('fs'); const XLSX = require('xlsx'); const { decrypt } = require('officecrypto-tool'); async function readProtectedXlsx(filePath, password) { const encryptedBuffer = fs.readFileSync(filePath); // 解密文件 const decryptedBuffer = await decrypt(encryptedBuffer, { password: password }); // 用原来的SheetJS逻辑解析解密后的内容 const workbook = XLSX.read(decryptedBuffer, { type: 'buffer' }); const first_sheet_name = workbook.SheetNames[0]; const worksheet = workbook.Sheets[first_sheet_name]; const jsonData = XLSX.utils.sheet_to_json(worksheet,{raw:true}); return jsonData; }
注意事项
- 传入的密码需要和文件设置的保护密码完全一致,否则依然会抛出解密失败错误
- 服务端使用时注意文件流的编码格式,避免二进制内容被转义导致解密失败
内容的提问来源于stack exchange,提问作者User1738
相关产品推荐
相关产品推荐

