|
@@ -0,0 +1,97 @@
|
|
|
|
|
+import ExcelJS from 'exceljs';
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+// 单sheet页导出
|
|
|
|
|
+//前端 导出 Excel
|
|
|
|
|
+export const useTableExcelExport = async (tableColumn:any[],tableData:any[],sheetName='sheet',excelName='excel' ) => {
|
|
|
|
|
+ // 1. 提取表头
|
|
|
|
|
+ const headers = tableColumn.map(column => column.label || column.name);
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 创建工作簿和工作表
|
|
|
|
|
+ const workbook = new ExcelJS.Workbook();
|
|
|
|
|
+ const worksheet = workbook.addWorksheet(sheetName);
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 添加表头行
|
|
|
|
|
+ const headerRow = worksheet.addRow(headers);
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 定义表头样式
|
|
|
|
|
+ headerRow.eachCell((cell) => {
|
|
|
|
|
+ cell.style = {
|
|
|
|
|
+ font: { name: 'Microsoft YaHei', size: 12, bold: true, color: { argb: 'FF333333' } },
|
|
|
|
|
+ fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFF4F6F8' } },
|
|
|
|
|
+ border: {
|
|
|
|
|
+ top: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
|
|
+ left: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
|
|
+ bottom: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
|
|
+ right: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
|
|
+ },
|
|
|
|
|
+ alignment: { vertical: 'middle', horizontal: 'left', wrapText: true },
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 添加数据行 __ 这个需要修改 ——待完善 ,数组形式 和 普通字符串形式
|
|
|
|
|
+ tableData.forEach(row => {
|
|
|
|
|
+
|
|
|
|
|
+ const rowData = tableColumn.map(column => {
|
|
|
|
|
+ const cellValue = row[column.name];
|
|
|
|
|
+ if (cellValue && Array.isArray(cellValue) && cellValue.length > 0) {
|
|
|
|
|
+ // 数组形式的处理方式,待定
|
|
|
|
|
+ return '-'
|
|
|
|
|
+ return cellValue.map((item: any) => item.label || '').join('\n');
|
|
|
|
|
+ }
|
|
|
|
|
+ return cellValue != null ? String(cellValue) : '-';
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const excelRow = worksheet.addRow(rowData);
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 定义数据行样式
|
|
|
|
|
+ excelRow.eachCell({ includeEmpty: true }, (cell) => {
|
|
|
|
|
+ cell.style = {
|
|
|
|
|
+ font: { name: 'Microsoft YaHei', size: 12, color: { argb: 'FF333333' } },
|
|
|
|
|
+ border: {
|
|
|
|
|
+ top: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
|
|
+ left: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
|
|
+ bottom: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
|
|
+ right: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
|
|
+ },
|
|
|
|
|
+ alignment: { vertical: 'top', horizontal: 'left', wrapText: true },
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 处理分组表头样式(仅针对每行的第一个单元格)
|
|
|
|
|
+ if (row.isHeader) {
|
|
|
|
|
+ // 获取该行的第一个单元格(列索引从 1 开始)
|
|
|
|
|
+ const firstCell = excelRow.getCell(1);
|
|
|
|
|
+ // 合并原有字体样式并加粗
|
|
|
|
|
+ firstCell.font = { ...firstCell.font, bold: true };
|
|
|
|
|
+ // 设置背景色
|
|
|
|
|
+ firstCell.fill = {
|
|
|
|
|
+ type: 'pattern',
|
|
|
|
|
+ pattern: 'solid',
|
|
|
|
|
+ fgColor: { argb: 'FFF4F6F8' }
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 8. 设置列宽
|
|
|
|
|
+ worksheet.columns = headers.map(() => ({ width: 25 }));
|
|
|
|
|
+
|
|
|
|
|
+ // 9. 导出文件
|
|
|
|
|
+ const buffer = await workbook.xlsx.writeBuffer();
|
|
|
|
|
+ const blob = new Blob([buffer], {
|
|
|
|
|
+ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const url = URL.createObjectURL(blob);
|
|
|
|
|
+ const link = document.createElement('a');
|
|
|
|
|
+ link.href = url;
|
|
|
|
|
+ link.download = `${excelName}_${new Date().toISOString().slice(0, 10)}.xlsx`;
|
|
|
|
|
+ link.style.visibility = 'hidden';
|
|
|
|
|
+ document.body.appendChild(link);
|
|
|
|
|
+ link.click();
|
|
|
|
|
+ document.body.removeChild(link);
|
|
|
|
|
+ URL.revokeObjectURL(url);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+
|