React中使用XLSX库导出Excel时销售数据未显示问题
销售报表Excel导出无数据问题排查与解决
问题现象
自研React管理后台使用XLSX库导出销售报表为Excel时,导出文件的「Sales Details」工作表无数据显示,但控制台打印原始salesData、处理后的salesTableData、生成的salesWS及工作簿工作表列表均正常。
用户代码
const handleExcelDownload = () => { console.log ("Starting Excel export with sales data:", salesData); const wb = XLSX.utils.book_new(); // Summary Sheet const summaryData = [ ['Sales Report', '', '', '', ''], ['Generated on:', new Date().toLocaleDateString(), '', '', ''], ['', '', '', '', ''], ['Summary Statistics', '', '', '', ''], ['', '', '', '', ''], ['Total Orders', totalSales, '', '', ''], ['Total Revenue', formatIndianRupee(totalAmount), '', '', ''], ['Total Discounts', formatIndianRupee(totalDiscount), '', '', ''], ['', '', '', '', ''] ]; const summaryWS = XLSX.utils.aoa_to_sheet(summaryData); XLSX.utils.book_append_sheet(wb, summaryWS, 'Summary'); // Sales data sheet const salesHeaders = [ ['Date', 'Order ID', 'Products', 'User', 'Amount', 'Discount', 'Status'] ]; // Convert sales data to rows const salesRows = salesData.map(sale => [ new Date(sale.date).toLocaleDateString(), sale.orderId, sale.products.map(p => `${p.name} (${p.quantity})`).join(', '), sale.userName, formatIndianRupee(sale.amount), formatIndianRupee(sale.discount), sale.status ]); // Combine headers and rows const salesTableData = [...salesHeaders, ...salesRows]; console.log("Sales Table Data:", salesTableData); // Debugging line // Create sales worksheet const salesWS = XLSX.utils.aoa_to_sheet(salesTableData); console.log("Sales Worksheet:", salesWS); // Debugging line // Set column widths const salesColWidth = [ { wch: 15 }, // Date { wch: 25 }, // Order ID { wch: 40 }, // Products { wch: 25 }, // User { wch: 15 }, // Amount { wch: 15 }, // Discount { wch: 15 } // Status ]; salesWS['!cols'] = salesColWidth; // Append sales worksheet to workbook XLSX.utils.book_append_sheet(wb, salesWS, 'Sales Details'); console.log("Workbook Sheets:", wb.SheetNames); // Debugging line // Save the file try { const date = new Date().toISOString().split('T')[0]; XLSX.writeFile(wb, `sales_report_${date}.xlsx`); console.log("Excel file generated successfully"); } catch (error) { console.error("Error generating Excel file:", error); } };
排查方向与解决方案
1. 切换XLSX库版本/导入方式
部分xlsx版本的aoa_to_sheet存在数组转工作表的隐性bug,可替换为xlsx-js-style(保留样式支持):
npm install xlsx-js-style --save
替换导入语句:
import XLSX from 'xlsx-js-style';
2. 改用JSON转工作表替代数组转工作表
放弃数组拼接方式,直接用json_to_sheet处理结构化数据,避免数组格式异常:
// 重构销售数据工作表生成逻辑 const salesWS = XLSX.utils.json_to_sheet(salesData.map(sale => ({ Date: new Date(sale.date).toLocaleDateString(), 'Order ID': sale.orderId, Products: sale.products.map(p => `${p.name} (${p.quantity})`).join(', '), User: sale.userName, Amount: formatIndianRupee(sale.amount), Discount: formatIndianRupee(sale.discount), Status: sale.status }))); // 保留列宽设置 salesWS['!cols'] = [ { wch: 15 }, { wch: 25 }, { wch: 40 }, { wch: 25 }, { wch: 15 }, { wch: 15 }, { wch: 15 } ];
3. 清理数据中的特殊字符
检查formatIndianRupee返回值是否包含不可见特殊字符,清理后再生成工作表:
// 格式化函数添加特殊字符清理 const formatIndianRupee = (amount) => { return `₹ ${amount.toLocaleString('en-IN')}`.replace(/[\u200B-\u200D\uFEFF]/g, ''); };
4. 强制同步工作表状态
极端情况下,追加工作表后手动更新工作簿引用:
XLSX.utils.book_append_sheet(wb, salesWS, 'Sales Details'); // 强制同步工作表引用 wb.Sheets['Sales Details'] = salesWS;
内容的提问来源于stack exchange,提问作者Abel Tomy
相关产品推荐
相关产品推荐

