纯前端 JavaScript 实现数据导出到 CSV 格式

CSV格式特点
日常开发中,数据导出到文件通常有两种方式:

  • 后端处理,以文件流或者资源路径的方式返回;
  • 后端返回数据,前端按需处理后再触发浏览器的下载事件,已保存到本地文件。

这里介绍后者的一种零依赖的实现方式。

保存内容到文件

通过 JS 创建一个隐藏的超链接,并主动点击触发下载事件。

/*** 保存内容到文件* @param {*} blob* @param {*} fileName*/
function saveToFile(blob, fileName = "下载文件.txt") {if (!(!!blob && blob.toString() == '[object Blob]')) {blob = new Blob([blob])}let link = document.createElement('a')link.href = window.URL.createObjectURL(blob)    // 创建下载的链接link.download = fileName                        // 下载后文件名link.style.display = 'none'document.body.appendChild(link)link.click()                                    // 点击下载window.URL.revokeObjectURL(link.href)           // 释放掉blob对象document.body.removeChild(link)                 // 下载完成移除元素
}

生成CSV格式

CSV(Comma-Separated Values,逗号分隔值)是一种纯文本格式,用于以表格形式存储数据,广泛应用于数据交换和处理,特别是在电子表格软件(如 Excel)和数据库系统之间的数据传输中。

处理起来也是比较简单,将二维数组中的子数组以分隔符(默认英文逗号)连接后以换行符拼接即可。这里需要注意特殊字段的处理:

  • 长字符串:特别是本身包含换行符(此时使用 ` 包裹)
  • 数组:通过换行符拼接
const NEW_LINE = "\n"/*** 处理特殊字符,若参数为数组则进行换行转换* @Param {*} v*/ 
const fixToCsv = v=>{if(Array.isArray(v))return `"${v.join(NEW_LINE).replace(/"/g, "`")}"`if(typeof(v)==='string')return `"${v.replace(/"/g, "`")}"`return v
}/*** 保存到 CSV 默认编码为 UTF-8* @param {Array|Object} obj - 数据对象,可以是二维数组/Object(包含 headers、rows 属性)* @param {String} fileName - 文件名* @param {String} newLine - 换行符,默认 \n*/
function saveToCSV(obj, fileName = "下载文件", newLine=NEW_LINE) {let csvText = ""//参数为数组的情况if(Array.isArray(obj)){csvText = Array.isArray(obj[0])? obj.map(v=>v.map(fixToCsv).join(",")).join(newLine): obj.join(newLine)}else if(typeof(obj) === 'object'){let { headers, rows } = objif(!headers && !Array.isArray(headers)) throw Error(`[CSV导出] Object 类型的参数必须传递 headers 属性`)//写入标题栏csvText += headers.map(h=> typeof(h)==='object'?h.text:h).join(",") + newLinelet headerIds = headers.map(h=> typeof(h)==='object'? h.key:h)rows.forEach((row,rIndex)=>{csvText += headerIds.map(id=>fixToCsv(row[id])).join(",") + newLine})}else if(typeof(obj) === 'string')csvText = objsaveToFile(new Blob([csvText], { type: "application/csv;charset=utf-8" }), `${fileName}.csv`)
}

如何使用

// 拿到后台数据
const rows = fetch("{API}")
let csv = []
csv.push(["序号","名称","联系方式"])
// 处理数据
rows.forEach((row, i)=>{csv.push([`${i+1}`,row.name, row.phone])
})saveToCSV(csv, "用户导出")

之后浏览器会下载最终的 CSV 文件(此时需要注意弹窗拦截)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/88855.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/88855.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

香港理工大学实验室定时预约

香港理工大学实验室定时预约 文章目录香港理工大学实验室定时预约简介接单价格软件界面网站预约界面代码对爬虫、逆向感兴趣的同学可以查看文章,一对一小班教学(系统理论和实战教程)、提供接单兼职渠道:https://blog.csdn.net/weixin_35770067/article/d…

Spring AI 项目实战(十七):Spring Boot + AI + 通义千问星辰航空智能机票预订系统(附完整源码)

系列文章 序号文章名称1Spring AI 项目实战(一):Spring AI 核心模块入门2Spring AI 项目实战(二):Spring Boot + AI + DeepSeek 深度实战(附完整源码)3Spring AI 项目实战(三):Spring Boot + AI + DeepSeek 打造智能客服系统(附完整源码)4

STM32CubeMX+CLion 使用ARM_CMSIS_DSP

安装 参考: 【CLion开发stm32】如何使用DSP库 - 未知的奇迹 - 博客园 实际上这样配置会出一点小问题,现对其修改 1. 项目根目录下新建 DSP_LIB文件夹 将目录STM32CubeMX\Repository\STM32Cube_FW_G4_V1.6.1\Drivers\CMSIS\DSP下的Include文件夹和So…

深入解析C#接口实现的两种核心技术:派生继承 vs 显式实现

—— 如何优雅解决多接口冲突问题 🔍 核心概念速览 派生成员实现 类通过继承基类方法隐式满足接口实现需求 interface IIfc1 { void PrintOut(string s); }class MyBaseClass { // 基类实现方法 public void PrintOut(string s) > Console.WriteLine($"Cal…

鸿蒙项目构建配置

鸿蒙项目构建配置 参考文档 深入鸿蒙开发之后,一般会遇到以下几个问题。 每次编译的时候需要手动配置不同的 versionCode 和 versionName;在使用 git 管理代码的时候,不同的人或者不在同一台电脑上,dev eco 这个编译器需要经常…

os.machine()详解

核心功能返回硬件架构 返回字符串表示系统的硬件架构,常见值包括: x86_64:64 位 x86 架构(Intel/AMD)armv7l:32 位 ARM 架构(如树莓派 3B)aarch64:64 位 ARM 架构&#x…

linux-shell脚本

linux-shell脚本一、什么是shell脚本?二、为什么要学习shell脚本?三、脚本执行的方式3.1 bash test.sh3.2 ./test.sh3.3 source test.sh3.4 . test.sh四、变量的使用4.1 变量定义与使用4.2 避免变量混淆4.3 位置变量for循环和位置变量的结合案例4.4 read…

【嵌入式】51单片机学习笔记-Keil5软件安装教程

00. 目录 文章目录00. 目录01. Keil C51概述02. Keil C51下载03. Keil C51安装04. Keil C51注册05. 附录01. Keil C51概述 Keil C51 是德国Keil公司(现被ARM收购)开发的嵌入式开发工具,专注于8051单片机的C语言和汇编开发。它是μVision IDE…

ai之 ubuntu本地安装mineru2.1.0

MinerU 目录 一、更新内容概述写在前面的话:总体来看,2.0版本升级为全新的 VLM 解析模式,更优于以前的基础解析方式。二、MinerU 安装部署下面使用源码来进行环境安装。注意:当前状态说明推荐解决方案如果是下载插件慢可以 指定阿里源三、MinerU 使用1. 在线体验2. 命令行使…

华为昇腾NPU与NVIDIA CUDA生态兼容层开发实录:手写算子自动转换工具链(AST级代码迁移方案)

点击 “AladdinEdu,同学们用得起的【H卡】算力平台”,H卡级别算力,按量计费,灵活弹性,顶级配置,学生专属优惠。 当国产AI芯片崛起遭遇生态壁垒,如何实现CUDA算子到昇腾平台的无损迁移成为关键挑…

GraphRAG Docker化部署,接入本地Ollama完整技术指南:从零基础到生产部署的系统性知识体系

相关推荐:Umi-OCR 的 Docker安装(win制作镜像,Linux(Ubuntu Server 22.04)离线部署) 一、技术背景与发展脉络 1.1 RAG技术演进历程分析 检索增强生成(RAG)技术的发展经历了三个重要…

Android 系统默认Launcher3 菜单模式双层改成单层-3

Android 系统默认自带Launcher3 菜单都为双层模式 各手机大厂的Launcher的菜单模式都为单层 如何将launcher3的菜单模式改为单层模式 mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel); mWidgetsButton = findViewById(R.id.widget_butto…

基于k8s环境下pulsar高可用测试和扩缩容(上)

#作者:任少近 文章目录Pulsar高可用测试1. 测试目的2.当前集群环境说明3. 模拟故障场景4.功能验证5.结论Pulsar高可用测试 1. 测试目的 本次测试旨在验证 Apache Pulsar 在某个 Broker 节点宕机(down)的情况下,是否仍能正常提供…

JAVA JVM垃圾收集

JVM 垃圾收集是 Java 自动内存管理的核心,本文通过围绕 “哪些是垃圾、何时回收、怎么回收、用啥回收器、内存咋分配” 等展开一、判断哪些是垃圾引用计数法:给对象分配引用计数器,有引用时计数加 1,引用失效减 1 ,计数…

UniHttp生命周期钩子与公共参数实战:打造智能天气接口客户端

> 通过灵活的生命周期钩子,我们让HTTP请求从机械操作进化为智能对话 在现代应用开发中,高效处理HTTP请求是核心能力。本文将深入探索UniHttp框架中强大的**HttpApiProcessor生命周期钩子**,并演示如何利用其**公共参数填充机制**优雅地处理第三方接口。我们将以百度天…

C++高级编程,类模版成员函数类外实现

#include <iostream> #include <string>//类模版成员函数类外实现 template<class T1,class T2> class Person {//Person构造函数 public:Person(T1 name,T2 age);// {// this->m_Namename;// this->m_Ageage;// }//Person的成员函数void show…

[Linux入门 ] RAID存储技术概述

一.数据存储架构 1️⃣存储系统 2️⃣主机系统 3️⃣互连部件 4️⃣存储设备与磁盘阵列 二.数据存储技术 1️⃣数据冗余技术 2️⃣RAID 0 3️⃣RAID 1 4️⃣RAID 2 5️⃣RAID 3 6️⃣RAID 4 三.基于硬件的RAID磁盘阵列 1️⃣阵列卡(RAID控制器) 2️⃣阵列卡种类 …

AI绘画生成章邯全身像提示词

融合了历史元素和视觉表现力&#xff0c;力求生成符合秦末名将章邯身份的全身像。 核心提示词结构&#xff1a; [主体描述]&#xff0c;[服装/盔甲细节]&#xff0c;[姿态/神情]&#xff0c;[武器]&#xff0c;[背景/氛围]&#xff0c;[风格/质量]&#xff0c;[参数] 选项一&…

iOS高级开发工程师面试——关于优化

iOS高级开发工程师面试——关于优化 一、TableView 有什么好的性能优化方案?二、界面卡顿和检测你都是怎么处理?三、谈谈你对离屏渲染的理解?四、如何降低APP包的大小?五、日常如何检查内存泄露?六、APP启动时间应从哪些方面优化?一、TableView 有什么好的性能优化方案?…

线性基学习笔记

我们称一个线性空间 V V V 的一个极大线性无关集为这个线性空间的线性基,简称基。 异或线性基 在异或空间下,我们定义如下内容。 异或和 设 S S