文章目录
- 效果
- 过程
- 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,UserNamelet 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 = 0for (let character of currentArrayString) {if (character === '"' && quoteFlag === 0) {quoteFlag = 1}else if (character === '"' && quoteFlag == 1) quoteFlag = 0if (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 CSVif (index === 'csv') {// 若输入的不是JSON,则清空if (!judgeJSON(fileContent)) {alert('输入的JSON格式错误!');clearFields();return;}const outputResult = JSONtoCSV(fileContent)const outputText = document.getElementById('outputText')outputText.value = outputResult}// CSV to JSONelse {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,UserNamelet 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 = 0for (let character of currentArrayString) {if (character === '"' && quoteFlag === 0) {quoteFlag = 1}else if (character === '"' && quoteFlag == 1) quoteFlag = 0if (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 = ''
}