文章目录
- 效果
- 过程
- 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 = ''
}