【前端demo】CSVJSON转换器 原生实现:CSV转换为JSON,JSON转换为CSV

news2024/12/25 21:19:40

文章目录

    • 效果
    • 过程
      • textarea
      • Tooltip提示工具
      • 按钮的min-width
      • 判断输入是否是CSV或JSON
      • JSON与CSV样例
      • JSON转为CSV
      • CSV转为JSON
      • 不足之处
    • 代码
      • HTML
      • CSS
      • JS

其他demo

效果

在这里插入图片描述

效果预览:CSV&JSON Converter (codepen.io)

参照的预览:JSV Converter(gpaiva00.github.io)

参考:

gpaiva00/json-csv: 💡 JSON ↔️ CSV Converter(github.com)

JSV Converter(gpaiva00.github.io)

JSON to CSV Converter(codepen.io)

CSV to JSON Converter(codepen.io)

过程

textarea

禁止拉伸

style="resize:none" 

选择textarea中的placeholder:用伪元素

textarea::placeholder{

}

选中textarea不出现边框

outline: none;

Tooltip提示工具

CSS 提示工具(Tooltip) | 菜鸟教程 (runoob.com)

效果是这样:鼠标悬停在按钮上就会显示提示。

在这里插入图片描述

其实是:

在这里插入图片描述
代码:https://www.runoob.com/try/try.php?filename=trycss_tooltip_arrow_left

/* tooltip和tooltiptext 鼠标悬停显示提示 */
.tooltip {
    position: relative;
    display: inline-block;
}

.tooltip .tooltiptext {
    visibility: hidden;
    width: 120px;
    background-color: black;
    color: #fff;
    text-align: center;
    border-radius: 6px;
    padding: 5px 0;
    position: absolute;
    z-index: 1;
    top: -5px;
    left: 110%;
}

.tooltip .tooltiptext::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 100%;
    margin-top: -5px;
    border-width: 5px;
    border-style: solid;
    border-color: transparent black transparent transparent;
}
.tooltip:hover .tooltiptext {
    visibility: visible;
}

.tooltip .tooltiptext::after是向左指的小箭头:

在这里插入图片描述

在这里插入图片描述

按钮的min-width

设置按钮min-width:如果是width:10vw,当窗口压缩到很小时,里面的字就压缩到看不到了 。

min-width: 10vw;

在这里插入图片描述

判断输入是否是CSV或JSON

要判断输入的CSV或JSON是否是对应类型,不是的话就alert提示,并不予转换。

// 判断是否是CSV或JSON
function judgeCSV(fileContent) {
    fileContent = fileContent.split(',')

    if (!fileContent.length) return false;

    for (let i = 0; i < fileContent.length; i++) {
        const item = fileContent[i].trim()
        if (!item.length) return false;
    }

    return true;
}

function judgeJSON(fileContent) {
    // 尝试解析,可以解析就是JSON,报错就不是
    try {
        JSON.parse(fileContent);
        return true;
    } catch (error) {
        return false;
    }
}

JSON与CSV样例

JSON:

[{"Id":1,"UserName":"Sam Smith"},
{"Id":2,"UserName":"Fred Frankly"},
{"Id":1,"UserName":"Zachary Zupers"}]

CSV:

Id,UserName
1,Sam Smith
2,Fred Frankly
1,Zachary Zupers

JSON转为CSV

  • 先判断是否是对象,不是的话就把JSON转为对象 JSON.parse()

  • 转为对象后看是否是数组,不是的话就转为数组(a转为数组的方法:[a])

  • '\r\n'是CSV的换行符

  • 先获取表头,即数组对象的key

  • 再获取内容,即所有对象的value

// 将JSON转换为CSV或反之
function JSONtoCSV(fileContent) {
    // 将JSON转换为对象
    const jsonInput = typeof fileContent != 'object' ? JSON.parse(fileContent) : fileContent;
    // 转为数组
    let arr = Array.isArray(jsonInput) ? jsonInput : [jsonInput];

    // 表头
    // 如:{ Id: 1, UserName: 'Sam Smith' } 的表头是 Id,UserName

    let ans = ''
    let head = Object.keys(arr[0]).join(',')

    // '\r\n'是CSV的换行符
    ans += head + '\r\n';

    // 内容
    arr.forEach(item => {
        let temp = Object.values(item).join(',');
        ans += temp + '\r\n';
    })

    console.log(ans)
    return ans;
}

参考:

最简单的JS实现json转csv - 阿李云 - 博客园
(cnblogs.com)

使用JavaScript 将Json数据导出CSV文件_javascript
json转csv_Blank__的博客-CSDN博客

CSV转为JSON

发现有很好用的库:

JS小知识,如何将 CSV 转换为 JSON 字符串_前端达人的博客-CSDN博客
csvjson CDN by jsDelivr - A CDN for npm and GitHub

然后发现原生引用库好像有点麻烦。所以还是手动实现。

步骤:在 JavaScript 中将 CSV 转换为 JSON | D栈 - Delft Stack

在这里插入图片描述
这里有一个坑,debugger很久才找出来。

参考链接里输入的CSV的,分隔符后有一个空格:, 。因此代码中也是用, 但我输入的CSV中,中没有空格。

// https://www.delftstack.com/zh/howto/javascript/csv-to-json-javascript/
function CSVtoJSON(fileContent) {
    console.log('------CSVtoJSON------')
    const array = fileContent.toString().split('\n')
    const csvToJsonResult = []
    console.log('array', array)

    // 表头
    const headers = array[0].split(',')

    for (let i = 1; i < array.length; i++) {
        /* Empty object to store result in key value pair */
        const jsonObject = {}
        /* Store the current array element */
        const currentArrayString = array[i]
        let string = ''

        let quoteFlag = 0
        for (let character of currentArrayString) {
            if (character === '"' && quoteFlag === 0) {
                quoteFlag = 1
            }
            else if (character === '"' && quoteFlag == 1) quoteFlag = 0
            if (character === ',' && quoteFlag === 0) character = '|'
            if (character !== '"') string += character
        }

        let jsonProperties = string.split("|")

        for (let j in headers) {
            if (jsonProperties[j].includes(",")) {
                jsonObject[headers[j]] = jsonProperties[j]
                    .split(",").map(item => item.trim())
            }
            else jsonObject[headers[j]] = jsonProperties[j]
        }
        /* Push the genearted JSON object to resultant array */
        csvToJsonResult.push(jsonObject)
    }
    /* Convert the final array to JSON */
    const json = JSON.stringify(csvToJsonResult);
    console.log(json)
    return json
}

不足之处

功能不够严谨,比如输入的CSV是以逗号,分隔,但逗号,后若用空格,理论上应该可以转换为JSON,但这里的代码并不能实现。

可以对输入的CSV预处理一下。

代码

HTML

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSV&JSON Converter</title>
    <link rel="stylesheet" href="style.css">
    <script src="index.js"></script>
</head>

<body>
    <div class="main">
        <div class="input item">
            <textarea name="" id="inputText" class="inputText" placeholder="请输入CSV或JSON" style="resize:none"></textarea>
        </div>
        <div class="btn">
            <!-- tooltip和tooltiptext 鼠标悬停显示提示 -->
            <button class="tooltip" onclick="handleConvert('csv')">CSV
                <span class="tooltiptext">JSON to CSV</span>
            </button>
            <button class="tooltip" onclick="handleConvert('json')">JSON
                <span class="tooltiptext">CSV to JSON</span>
            </button>
        </div>
        <div class="output item">
            <textarea name="" id="outputText" class="outputText" readonly style="resize:none"></textarea>
        </div>
    </div>
</body>

</html>

CSS

body {
    background-color: #f2efea;
}

.main {
    display: flex;
    margin-top: 15vh;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 60vh;
}


.item textarea {
    width: 400px;
    height: 350px;
    background-color: #413e3e;
    border: 15px solid #525252;
    border-radius: 20px;
    padding: 10px;
    color: white;
    /* 选中之后不出现边框 */
    outline: none;
}



.item textarea::placeholder {
    font-size: 16px;
}

.btn {
    display: flex;
    flex-direction: column;
    margin: 0 20px;
}

.btn button {
    height: 50px;
    margin: 15px 0;
    /* 如果是width:10vw 当窗口压缩到很小时,里面的字就压缩到看不到了 */
    min-width: 10vw;
    font-size: 15px;
    border-radius: 5px;
    border: 1px solid;
    color: white;
}

/* first-child button的父元素的首个子button */
button:first-child {
    background-color: #805e73;
}

button:nth-child(2) {
    background-color: #87bcde;
}

/* tooltip和tooltiptext 鼠标悬停显示提示 */
.tooltip {
    position: relative;
    display: inline-block;
}

.tooltip .tooltiptext {
    visibility: hidden;
    width: 115px;
    background-color: black;
    color: #fff;
    text-align: center;
    border-radius: 4px;
    padding: 4px 0;
    position: absolute;
    z-index: 1;
    top: -5px;
    left: 110%;
}

/* 向左指的小箭头 */
.tooltip .tooltiptext::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 100%;
    margin-top: -5px;
    border-width: 5px;
    border-style: solid;
    border-color: transparent black transparent transparent;
}

.tooltip:hover .tooltiptext {
    visibility: visible;
}

JS

// const inputText = document.getElementById('inputText')
// const outputText = document.getElementById('outputText')


function handleConvert(index) {
    const inputText = document.getElementById('inputText')
    console.log(inputText.value)
    const fileContent = String(inputText.value).trim()

    // 若输入为空
    if (!fileContent.length) return;

    // JSON to CSV
    if (index === 'csv') {
        // 若输入的不是JSON,则清空
        if (!judgeJSON(fileContent)) {
            alert('输入的JSON格式错误!');
            clearFields();
            return;
        }

        const outputResult = JSONtoCSV(fileContent)
        const outputText = document.getElementById('outputText')
        outputText.value = outputResult
    }
    // CSV to JSON
    else {
        if (!judgeCSV(fileContent)) {
            alert('输入的CSV格式错误!');
            clearFields();
            return;
        }

        try {
            const outputResult = CSVtoJSON(fileContent)
            const outputText = document.getElementById('outputText')
            outputText.value = outputResult
        } catch (error) {
            // alert('输入的CSV格式错误!')
            return;
        }

    }
}

// 判断是否是CSV或JSON
function judgeCSV(fileContent) {
    fileContent = fileContent.split(',')

    if (!fileContent.length) return false;

    for (let i = 0; i < fileContent.length; i++) {
        const item = fileContent[i].trim()
        if (!item.length) return false;
    }

    return true;
}

function judgeJSON(fileContent) {
    // 尝试解析,可以解析就是JSON,报错就不是
    try {
        JSON.parse(fileContent);
        return true;
    } catch (error) {
        return false;
    }
}

// 将JSON转换为CSV或反之
function JSONtoCSV(fileContent) {
    // 将JSON转换为对象
    const jsonInput = typeof fileContent != 'object' ? JSON.parse(fileContent) : fileContent;
    // 转为数组
    let arr = Array.isArray(jsonInput) ? jsonInput : [jsonInput];

    // 表头
    // 如:{ Id: 1, UserName: 'Sam Smith' } 的表头是 Id,UserName

    let ans = ''
    let head = Object.keys(arr[0]).join(',')

    // '\r\n'是CSV的换行符
    ans += head + '\r\n';

    // 内容
    arr.forEach(item => {
        let temp = Object.values(item).join(',');
        ans += temp + '\r\n';
    })

    console.log(ans)
    return ans;
}

// https://www.delftstack.com/zh/howto/javascript/csv-to-json-javascript/
function CSVtoJSON(fileContent) {
    console.log('------CSVtoJSON------')
    const array = fileContent.toString().split('\n')
    const csvToJsonResult = []
    console.log('array', array)

    // 表头
    const headers = array[0].split(',')

    for (let i = 1; i < array.length; i++) {
        /* Empty object to store result in key value pair */
        const jsonObject = {}
        /* Store the current array element */
        const currentArrayString = array[i]
        let string = ''

        let quoteFlag = 0
        for (let character of currentArrayString) {
            if (character === '"' && quoteFlag === 0) {
                quoteFlag = 1
            }
            else if (character === '"' && quoteFlag == 1) quoteFlag = 0
            if (character === ',' && quoteFlag === 0) character = '|'
            if (character !== '"') string += character
        }

        let jsonProperties = string.split("|")

        for (let j in headers) {
            if (jsonProperties[j].includes(",")) {
                jsonObject[headers[j]] = jsonProperties[j]
                    .split(",").map(item => item.trim())
            }
            else jsonObject[headers[j]] = jsonProperties[j]
        }
        /* Push the genearted JSON object to resultant array */
        csvToJsonResult.push(jsonObject)
    }
    /* Convert the final array to JSON */
    const json = JSON.stringify(csvToJsonResult);
    console.log(json)
    return json
}

// 清空输出框
function clearFields() {
    outputText.value = ''
}

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

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

相关文章

地毯16 CFR 1630/1631安全防火性易燃性测试

地毯的16 CFR 1630/1631安全防火性易燃性测试是一项重要的产品检测认证标准。该测试旨在评估地毯材料的防火性能&#xff0c;以确保其在使用过程中不会引发火灾或加剧火势。测试过程包括对地毯样品进行燃烧测试和燃烧后的评估。 根据16 CFR 1630标准&#xff0c;地毯样品将被暴…

检漏仪和高真空度控制技术在热管漏率和内部真空度测量中的应用

摘要&#xff1a;大量MEMS真空密封件具有小体积、高真空和无外接通气接口的特点&#xff0c;现有的各种检漏技术无法对其进行无损形式的漏率和内部真空度测量。基于压差法和高真空度恒定控制技术&#xff0c;本文提出了解决方案。方案的具体内容是将被测封装器件放置在一个比器…

elementui表格自定义表头的两种方法

表格自定义表头的方式 多选框表头换文字 请查看上篇博客&#xff1a;http://t.csdn.cn/69De2 文字换按钮 render-header render-header方法详情 Table-column Attributes 参数说明类型可选值默认值render-header列标题 Label 区域渲染使用的 FunctionFunction(h, { column, $in…

恒运资本:北向资金流出一定会跌吗?股票涨跌与什么有关?

北向资金被认为是A股商场的风向标&#xff0c;它的动向往往会影响投资者的心情。那么北向资金流出一定会跌吗&#xff1f;股票涨跌与什么有关&#xff1f;恒运资本也为大家准备了相关内容&#xff0c;以供参阅。 北向资金流出一定会跌吗&#xff1f; 北向资金流出并不一定意味…

快速解决 adb server version doesn‘t match this client

这个问题是由于电脑上安装了多个版本的adb工具&#xff0c;客户端和服务端的版本不一致&#xff0c;无法正常通信导致。最快的解决方法就是将Android SDK中adb复制到系统目录下。 操作步骤如下&#xff1a; 1. 查看adb版本和路径 执行adb version&#xff0c;如下&#xff0…

手机无人直播软件在苹果iOS系统中能使用吗?

在现代社交媒体的时代&#xff0c;直播带货已经成为了一种热门的销售途径。通过直播&#xff0c;人们可以远程分享自己的商品&#xff0c;与观众进行互动&#xff0c;增强沟通和参与感。而如今&#xff0c;手机无人直播软件更是成为了直播带货领域的一项火爆的技术。那么&#…

渗透测试——安全漏洞扫描工具APPScan的安装与基本使用步骤

前言 HCL AppScan Standard是安全专家和渗透测试者设计的动态应用程序安全测试工具&#xff0c;AppScan使用强大的扫描引擎&#xff0c;会自动检索目标应用程序并测试漏洞。测试结果按优先级排列&#xff0c;允许操作员快速分类问题、发现最关键的漏洞。每个检测到的问题都可以…

Python 自学:使用线程模块同时运行代码 Threading

1. 以下代码中&#xff0c;程序会等一个函数执行完毕才执行下一个函数。 import timestart time.perf_counter()def do_something():print(Sleeping 1 second...)time.sleep(1)print(Done Sleeping...)do_something() do_something()finish time.perf_counter()print(fFinis…

惠普NS1005 NS1020打印机如何判断是不是该加粉了

惠普 Laser NS MFP 1005 1020系列智能闪充加粉式多功能一体机的耗材余量指示灯显示“1” “2” “2”时&#xff0c;就是在“说”&#xff1a;快没有墨粉了&#xff1b; 耗材余量指示灯和充粉口指示灯 在不同的状态下代表不同的意思&#xff0c;当耗材余量指示灯显示“1” “2”…

2023年9月上海/广州/深圳CSPM-3国标项目管理中级认证招生

CSPM-3中级项目管理专业人员评价&#xff0c;是中国标准化协会&#xff08;全国项目管理标准化技术委员会秘书处&#xff09;&#xff0c;面向社会开展项目管理专业人员能力的等级证书。旨在构建多层次从业人员培养培训体系&#xff0c;建立健全人才职业能力评价和激励机制的要…

【数据结构-栈】栈基础

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

java持久化框架JPA,自动执行sql语句的代码实现

在springboot入口处调用&#xff1a; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBoot…

Mac使用VMWare安装centos7回车回退

Mac使用VMWare安装centos7回车回退 说明&#xff1a;本人电脑是MacBook 14pro M2芯片&#xff0c;安装的为VMWare16.2.5&#xff0c;Centos版本为centos stream9 解决方法&#xff1a;使用VM16.2.5Stream9Debian 11操作系统正常安装 问题&#xff1a;下载了VMWare16和Centos…

【微服务部署】五、Jenkins+Docker一键打包部署NodeJS(Vue)项目的Docker镜像步骤详解

NodeJS&#xff08;Vue&#xff09;项目也可以通过打包成Docker镜像的方式进行部署&#xff0c;原理是先将项目打包成静态页面&#xff0c;然后再将静态页面直接copy到Nginx镜像中运行。 一、服务器环境配置 前面说明了服务器Nginx的安装和配置&#xff0c;这里稍微有些不同&a…

java线程和go协程

一、线程的实现 线程的实现方式主要有三种&#xff1a;内核线程实现、用户线程实现、用户线程加轻量级进程混合实现。因为自己只对java的线程比较熟悉一点&#xff0c;所以主要针对java线程和go的协程之间进行一个对比。 线程模型主要有三种&#xff1a;1、内核级别线程&#…

微服务主流框架概览

微服务主流框架概览 目录概述需求&#xff1a; 设计思路实现思路分析1.HSF2.Dubbo 3.Spring Cloud5.gRPC Service mesh 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a be…

深入理解作用域、作用域链和闭包

​ &#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4da; 前言 &#x1f4d8; 1. 词法作用域 &#x1f4d6; 1.2 示例 &#x1f4d6; 1.3 词法作用域的…

医学专题-多组学在疾病发生发展过程中的研究思路

研究背景 单一组学数据分析通常用来解释某种特征性的生化指标与某些疾病之间的关联&#xff0c;但无法说明其中复杂的因果关系。从疾病表型或某种生物现象出发&#xff0c;寻找影响疾病发生发展的关键因子或通路&#xff0c;借助高通量的技术手段&#xff0c;设置相应的患者组…

49、IDEA 创建类或方法时,实现按格式化 ctrl + alt + l 能变成左花括号在下一行,与右花括号对齐

IDEA 创建类或方法时&#xff0c;左花括号是改成在下一行&#xff0c;与右花括号对齐 默认花括号是这样的 现在想改成这样的 实现按格式化 ctrl alt l 能变成这样 在这里修改就行 把 end of line 改成 next line

基于SSM框架金鱼销售平台源码和论文

基于SSM框架金鱼销售平台源码和论文120 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优…