目录
1.说明
在开发中经常会出现下载csv或者excel文件,可以通过后端下载,也可以通过前端下载,如果在前端页面中可以直接获取到要下载的数据,可以通过前端下载的方式,更加高效便捷
2.示例--excel
①安装依赖
npm install xlsx
# 或者
yarn add xlsx
②在目标文件中引入依赖
import * as XLSX from 'xlsx';
③根据页面中的数据,生成excel文件
const exportToExcel = async () => {
const orderedCheckedRecords = await getOrderSelData()
if (!orderedCheckedRecords || orderedCheckedRecords.length === 0) {
MessageBox.error('请选择要导出的数据');
return;
}
// 获取有效列信息,删除敏感列信息
const col: [] = await getNoSensitivityCol({colList: tableCol.value})
// 获取表头并添加类型
const headers: ColumnHeader[] = col
.filter((col: any) => col.visible == 1)
.map((col: any) => ({
title: col.title,
dataIndex: col.dataIndex
}));
// 构建Excel数据
const excelData = orderedCheckedRecords.map((record: any) => {
const row: any = {};
headers.forEach((header: ColumnHeader) => {
row[header.dataIndex] = record[header.dataIndex];
});
return row;
});
// 创建工作簿
const wb = XLSX.utils.book_new();
// 创建工作表 - 使用类型定义
const ws = XLSX.utils.json_to_sheet(excelData, {
header: headers.map((h: ColumnHeader) => h.dataIndex)
});
// 添加表头标题行
XLSX.utils.sheet_add_aoa(ws, [headers.map((h: ColumnHeader) => h.title)
], {origin: 'A1'});
// 设置列宽
const colWidth = headers.map(() => ({wch: 10}));
ws['!cols'] = colWidth;
const fileName = prop.docName ?? '数据导出'
// 将工作表添加到工作簿
XLSX.utils.book_append_sheet(wb, ws, 'data');
// 生成Excel文件并下载
XLSX.writeFile(wb, `${fileName}.xlsx`);
};
在前端页面中获取要下载的数据信息及文件标题信息
构建导出数据信息,每条数据的对象中的的key我使用的是每列的唯一标识,即dataIndex,value为列标识,并对要导出的列信息进行了过滤处理,只导出必要的列信息
创建工作表,做好数据和表头的对应,
添加标题行,并设置列宽
设置导出的sheet名,注意名称有长度限制,不要超过30位,
3.示例--csv
const exportToCSV = async () => {
const orderedCheckedRecords = await getOrderSelData();
if (!orderedCheckedRecords || orderedCheckedRecords.length === 0) {
MessageBox.error('请选择要导出的数据');
return;
}
// 获取有效列信息,删除敏感列信息
const col: [] = await getNoSensitivityCol({colList: tableCol.value})
// 获取表头
const headers = col
.filter((col: any) => col.visible == 1)
.map((col: any) => ({
title: col.title,
dataIndex: col.dataIndex
}));
// 构建CSV数据
let csvContent = '\ufeff'; // 添加BOM标记以支持中文
// 添加表头
csvContent += headers.map((h: ColumnHeader) => `"${h.title}"`).join(',') + '\n';
// 添加数据行
orderedCheckedRecords.forEach((record: any) => {
const row = headers.map((header: ColumnHeader) => {
const value = record[header.dataIndex];
// 处理包含逗号、引号或换行符的值
if (value === null || value === undefined) {
return '""';
}
const stringValue = String(value);
if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) {
return `"${stringValue.replace(/"/g, '""')}"`;
}
return `"${stringValue}"`;
});
csvContent += row.join(',') + '\n';
});
// 创建Blob对象
const blob = new Blob([csvContent], {type: 'text/csv;charset=utf-8'});
// 创建下载链接
const fileName = prop.docName ?? '数据导出'
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `${fileName}.csv`;
// 触发下载
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
生成csv文件时要注意对中文的处理以及对特殊字符的处理,因为csv是通过逗号进行区分的
CSV 文件有以下规则需要遵守:
-
包含逗号的值必须用引号包裹,否则会被解析为多个列
-
包含换行符的值必须用引号包裹
-
如果值本身包含引号,需要将引号转义为两个引号
-
统一用引号包裹所有值可以避免很多解析问题