使用Excel.js导出用户列表至Xlsx遇障,求专家指导及简便方案
问题分析与解决方案
核心矛盾点拆解
你的代码存在几个关键问题,直接导致导出失败:
- 格式完全冲突:后端用Excel.js生成Excel工作簿,却强行转成CSV格式输出,前端又要保存为xlsx文件,格式不匹配自然无法打开。
- 二进制数据损坏:后端把Excel的二进制buffer转成字符串发送,破坏了文件的二进制结构,前端拿到的是无效数据。
- 前端接收方式错误:用
response.text()接收二进制文件,会导致编码混乱,无法还原成有效Excel文件。
修正后的后端代码(直接输出Excel二进制)
export const getUserExcel = async (req, res) => { try { const users = await User.find({}); const workbook = new exceljs.Workbook(); const sheet = workbook.addWorksheet("users"); const header = [ { header: "用户名", key: "userName", width: 20 }, { header: "名字", key: "firstName", width: 20 }, { header: "姓氏", key: "lastName", width: 20 }, { header: "邮箱", key: "email", width: 20 }, { header: "角色", key: "role", width: 20 }, ]; sheet.columns = header; users.forEach((user) => sheet.addRow(user.toObject())); sheet.getRow(1).eachCell((cell) => { cell.font = { bold: true }; }); // 设置正确的Excel响应头 res.setHeader( "Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ); res.setHeader( "Content-Disposition", "attachment; filename=users.xlsx" ); // 直接发送二进制buffer,不做字符串转换 const buffer = await workbook.xlsx.writeBuffer(); res.send(buffer); } catch (error) { console.error("导出用户失败:", error); res.status(500).send({ message: "服务器内部错误" }); } };
修正后的前端代码
const handleExport = async () => { try { const response = await fetch("/api/user/get-user-excel"); if (!response.ok) throw new Error("请求失败"); const blob = await response.blob(); fileSaver.saveAs(blob, "users.xlsx"); } catch (error) { console.error("下载Excel失败:", error); } };
更简便的替代方案(SheetJS/xlsx库)
如果觉得Excel.js操作繁琐,可以用SheetJS的xlsx库,前后端都能快速实现导出:
后端实现
import XLSX from 'xlsx'; export const getUserExcel = async (req, res) => { try { const users = await User.find({}).lean(); // 直接获取普通对象,无需toObject()转换 // 把JSON转成工作表 const worksheet = XLSX.utils.json_to_sheet(users, { header: ["userName", "firstName", "lastName", "email", "role"], skipHeader: false }); // 替换表头为中文 XLSX.utils.sheet_add_aoa(worksheet, [["用户名", "名字", "姓氏", "邮箱", "角色"]], { origin: "A1" }); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, "users"); // 生成Excel二进制buffer const buffer = XLSX.write(workbook, { type: "buffer", bookType: "xlsx" }); res.setHeader( "Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ); res.setHeader( "Content-Disposition", "attachment; filename=users.xlsx" ); res.send(buffer); } catch (error) { console.error("导出用户失败:", error); res.status(500).send({ message: "服务器内部错误" }); } };
前端实现
和之前修正后的前端代码完全一致,无需改动。
内容的提问来源于stack exchange,提问作者Fraz Khan
相关产品推荐
相关产品推荐

