前端开发-如何生成并导出xlsx或者csv文件
全栈老韩
全栈工程师,擅长iOS App开发、前端(vue、react、nuxt、小程序&Taro)开发、Flutter、React Native、后端(midwayjs、golang、express、koa)开发、docker容器、seo优化等。
在前端开发中,尤其是一些管理后台的开发项目中,经常有需要生成并导出表格的场景。最常见的表格格式莫过于xlsx和csv这两种格式的excel文件。
这种场景有两种实践:
- 服务端生成了excel表格,将文件uri网络地址通过接口传给前端,前端使用
window.location.href或者window.open等方法使用跳转下载这个uri对应的表格文件。 - 前端根据已有的数据,自行生成excel表格,实现自动下载文件。
第1个实践对于前端来说是比较方便的,今天我们介绍第2个实践。介绍的包含2种格式(xlsx、csv)的文件生成和下载,推荐xlsx格式的excel。
一、xlsx格式excel文件生成和下载
这种方式通过使用前端库xlsx来实现:
package.json
...
"dependencies": {
...
"xlsx": "^0.18.5",
...
}
...
封装代码:
xlsxFileHandle.ts
import * as XLSX from 'xlsx';
export interface excelType {
json: object;
name: string;
titleArr: string[];
sheetName: string;
}
/**
* 导出成xlsx文件
* @param params 传入的数据格式
*/
export const exportExcel = (params: excelType) => {
const keyArray = [];
let data = [];
const getLength = function (obj: object) {
let count = 0;
for (const i in obj) {
if (Object.prototype.hasOwnProperty.call(obj, i)) {
count++;
}
}
return count;
};
for (const key1 in params.json) {
if (Object.prototype.hasOwnProperty.call(params.json, key1)) {
const element = (params.json as { [key: string]: object })[key1];
const rowDataArray = [];
for (const key2 in element) {
if (Object.prototype.hasOwnProperty.call(element, key2)) {
const element2 = (element as { [key: string]: object })[key2];
rowDataArray.push(element2);
if (keyArray.length < getLength(element)) {
keyArray.push(key2);
}
}
}
data.push(rowDataArray);
}
}
data.splice(0, 0, params.titleArr as any);
data = data.filter(e => e.length > 0)
console.log(data);
let ws = XLSX.utils.aoa_to_sheet(data);
let wb = XLSX.utils.book_new();
// 隐藏英文字段表头
const wsrows = [{ hidden: false }];
/* 设置worksheet每列的最大宽度 */
const colWidth = data.filter(e => e.length > 0).map((row) =>
row.map((val) => {
/* 先判断是否为null/undefined */
if (val == null) {
return {
wch: 20,
};
} else if (val.toString().charCodeAt(0) > 255) {
/* 再判断是否为中文 */
return {
wch: val.toString().length * 2,
};
} else {
return {
wch: val.toString().length*2,
};
}
})
);
/* 以第一行为初始值 */
const result = colWidth[1];
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j].wch < colWidth[i][j].wch) {
result[j].wch = colWidth[i][j].wch;
}
}
}
ws['!cols'] = result;
ws['!rows'] = wsrows; // ws - worksheet
XLSX.utils.book_append_sheet(wb, ws, params.sheetName);
/* generate file and send to client */
XLSX.writeFile(wb, `${params.name}.xlsx`);
};
使用实例代码:
payExport.ts
import { exportExcel } from "../xlsxFileHandle"
/**
* 导出成xlsx文件
*/
export const ExportForXlsx = (batch_id: number, valueList: Array<xxxListItem>) => {
const titleList = [
"ID",
"订单ID",
"姓",
"名",
"收款人名字",
"电话",
"账号号码",
"银行名字",
"账号名字",
"收款金额",
"选填,附言",
"扣款金额",
"汇率",
"手续费$",
"创建时间",
"完成时间",
"订单状态",
]
const getStatusDesc = (status: number) => {
if (status == 1) {
return '待付款'
}
if (status == 2) {
return '失败'
}
if (status == 3) {
return '成功'
}
if (status == 4) {
return '处理中'
}
if (status == 5) {
return '失败-系统'
}
return '未知'
}
const newValueList = valueList.map(e => {
return {
"ID" : e.payee_id + '',
"订单ID": e.order_id + '',
"姓": e.last_name + '',
"名": e.first_name + '',
"收款人名字": e.payee_name + '',
"电话": e.phone_number + '',
"账号号码": e.account_id + '',
"银行名字": e.back_name + '',
"账号名字": e.bank_account_number + '',
"收款金额": e.receive_amount + '',
"选填,附言": e.remark + '',
"扣款金额": e.buckle_amount + '',
"汇率": e.exchange_rate + '',
"手续费$": e.handling_fee + '',
"创建时间": e.create_time + '',
"完成时间": (e.complete_time > 0 ? moment(e.complete_time).format('YYYY-MM-DD HH:mm:ss') : e.complete_time) + '',
"订单状态": getStatusDesc(e.status) + ''
}
})
const tableName = '支付-' + batch_id //表名
exportExcel({
json: newValueList,//数据
name: tableName, // 表名
titleArr: titleList,//表头
sheetName: batch_id + '',//页签
})
}
以上方法得到的效果:

二、csv格式excel文件生成和下载
不使用任何库,而是将数据合成字符串。
封装代码:
csvFile.ts
/**
* 导出成.csv格式的表格
* @param titleList 比如:['ID', '姓名', '年龄']
* @param valueList 比如:[ [1, '张三', 28], [2, '李四', 22] ]
*/
export const extractCsvFileFromData = (titleList: Array<string>, valueList: Array<any>) => {
const totalList = [titleList, ...valueList]
// 将数据转换为CSV格式的字符串
let csvContent = "data:text/csv;charset=utf-8,";
totalList.forEach((row, index) => {
if (index > 0) {
csvContent += "\n";
}
csvContent += row.join(",");
});
// 创建一个可下载的链接
const encodedUri = encodeURI(csvContent);
const link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "数据.csv");
document.body.appendChild(link); // 需要添加到body
link.click();
}
使用示例代码:
pay.ts
import moment from "moment"
/**
* 将明细列表,生成csv文件
* @param valueList 明细列表数据
*/
export const GenerateCSVFileFrom = (valueList: Array<xxxListItem>) => {
const titleList = [
"ID",
"订单ID",
"姓",
"名",
"收款人名字",
"电话",
"账号号码",
"银行名字",
"账号名字",
"收款金额",
"选填,附言",
"扣款金额",
"汇率",
"手续费$",
"创建时间",
"完成时间",
"订单状态",
]
const getStatusDesc = (status: number) => {
if (status == 1) {
return '待付款'
}
if (status == 2) {
return '失败'
}
if (status == 3) {
return '成功'
}
if (status == 4) {
return '处理中'
}
if (status == 5) {
return '失败-系统'
}
return '未知'
}
const newValueList = valueList.map(e => {
return [
e.payee_id + '', e.order_id + '', e.last_name + '', e.first_name + '',
e.payee_name + '', e.phone_number + '', e.account_id + '', e.back_name + '',
e.bank_account_number + '', e.receive_amount + '', e.remark + '', e.buckle_amount + '',
e.exchange_rate + '', e.handling_fee + '', e.create_time + '', (e.complete_time > 0 ? moment(e.complete_time).utcOffset(-5).format('YYYY-MM-DD HH:mm:ss') : e.complete_time) + '',
getStatusDesc(e.status) + ''
]
})
extractCsvFileFromData(titleList, newValueList)
}
以上就是在前端开发中,生成和导出xlsx和csv格式的excel文件的简单实践,希望对大家有帮助。
发布于2024-11-27 11:41:32
浏览量1218·
暂无评论,快来发表第一条评论吧