如何用JS数组/JSON+样式生成XLSX?alasql样式失效求助
我懂你现在的困扰——用alasql生成XLS文件时总会弹出文件验证的提示,换成XLSX格式后之前设置的样式又完全不生效。这里给你两个靠谱的解决方案,附可直接运行的代码示例:
方案1:使用SheetJS + xlsx-style实现带样式的XLSX导出
这个组合是前端处理Excel导出(含样式)的主流方案,兼容性和样式支持都比alasql更稳定,完全符合XLSX格式标准,不会出现文件损坏提示。
完整可运行代码(模拟Fiddle环境)
<!DOCTYPE html> <html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx-style/0.8.13/xlsxstyle.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js"></script> </head> <body ng-app="myApp" ng-controller="myCtrl"> <button ng-click="exportData()">导出XLSX</button> <script> var app = angular.module('myApp', []); app.controller('myCtrl', function($scope) { $scope.items = [{name: "nikki", sur: 1001, pos: '', data5 : "FSSS SDFGFD ",data6 : 323}]; $scope.exportData = function () { // 定义表头映射、列宽 const headerMap = [ { key: 'name', title: 'Name', width: 100 }, { key: 'sur', title: 'Sur', width: 100 }, { key: 'pos', title: 'Position', width: 100 }, { key: 'data5', title: '01/01/2017', width: 100 }, { key: 'data6', title: '02/01/2017', width: 100 } ]; // 构建工作表数据:先加表头,再加内容行 const wsData = [headerMap.map(h => h.title)]; $scope.items.forEach(item => { wsData.push(headerMap.map(h => item[h.key] || '')); }); // 创建基础工作表 const ws = XLSX.utils.aoa_to_sheet(wsData); // 设置列宽(转换为Excel支持的像素单位) ws['!cols'] = headerMap.map(h => ({ wpx: h.width })); // 给指定单元格设置背景色(对应原需求里第1行的第4、5列) const bgStyle = { fill: { fgColor: { rgb: '9BC2E6' } } // rgb(155,194,230)的十六进制值 }; ws['D1'].s = bgStyle; ws['E1'].s = bgStyle; // 创建带标题的工作表(实现原需求的caption效果) const captionWs = XLSX.utils.aoa_to_sheet([['Demo File']]); // 合并标题行的所有单元格 captionWs['!merges'] = [{ s: { r: 0, c: 0 }, e: { r: 0, c: headerMap.length - 1 } }]; // 设置标题样式:加粗、居中、大号字体 captionWs['A1'].s = { font: { bold: true, sz: 14 }, alignment: { horizontal: 'center' } }; // 合并标题和数据工作表 const combinedWs = XLSX.utils.sheet_add_aoa(captionWs, wsData, { origin: 1 }); combinedWs['!cols'] = ws['!cols']; // 重新给数据行的对应单元格设置样式 combinedWs['D2'].s = bgStyle; combinedWs['E2'].s = bgStyle; // 创建工作簿并导出 const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, combinedWs, 'MyFile'); XLSX.writeFile(wb, 'john.xlsx'); }; }); </script> </body> </html>
方案优势
- 完全遵循XLSX格式标准,导出的文件不会出现验证提示
- 样式控制精准,支持背景色、字体、对齐、合并单元格等多种需求
- 社区活跃,遇到问题容易找到解决方案
方案2:改进alasql的XLSX样式支持(如果坚持用alasql)
如果你不想更换库,可以结合SheetJS构建带样式的工作表,再用alasql的XLSXRAW命令导出,避开alasql原生XLSX样式支持的缺陷:
$scope.exportData = function () { // 先通过SheetJS构建带样式的工作表(逻辑参考方案1) const headerMap = [ { key: 'name', title: 'Name', width: 100 }, { key: 'sur', title: 'Sur', width: 100 }, { key: 'pos', title: 'Position', width: 100 }, { key: 'data5', title: '01/01/2017', width: 100 }, { key: 'data6', title: '02/01/2017', width: 100 } ]; const wsData = [headerMap.map(h => h.title)]; $scope.items.forEach(item => { wsData.push(headerMap.map(h => item[h.key] || '')); }); const ws = XLSX.utils.aoa_to_sheet(wsData); ws['!cols'] = headerMap.map(h => ({ wpx: h.width })); const bgStyle = { fill: { fgColor: { rgb: '9BC2E6' } } }; ws['D1'].s = bgStyle; ws['E1'].s = bgStyle; // 用alasql的XLSXRAW命令导出已带样式的工作表 alasql('SELECT * INTO XLSXRAW("john.xlsx",{sheetid:"MyFile"}) FROM ?', [ws]); };
这个方法相当于用SheetJS处理样式,alasql负责最后的导出操作,兼顾了你对alasql的使用习惯和样式需求。
内容的提问来源于stack exchange,提问作者Niraj Sazzie
相关产品推荐
相关产品推荐

