我的CSV数据是这样的:
heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2
...
如何使用JavaScript读取数据并将其转换为这样的数组?:
[
heading1: value1_1,
heading2: value2_1,
heading3: value3_1,
heading4: value4_1
heading5: value5_1
],[
heading1: value1_2,
heading2: value2_2,
heading3: value3_2,
heading4: value4_2,
heading5: value5_2
]
....
我试过这个代码,但运气不好!:
<script type="text/javascript">
var allText =[];
var allTextLines = [];
var Lines = [];
var txtFile = new XMLHttpRequest();
txtFile.open("GET", "file://d:/data.txt", true);
txtFile.onreadystatechange = function()
{
allText = txtFile.responseText;
allTextLines = allText.split(/\r\n|\n/);
};
document.write(allTextLines);
document.write(allText);
document.write(txtFile);
</script>
下面是另一种将外部CSV读入Javascript的方法(使用jQuery)。
它有点冗长,但我觉得通过将数据读入数组,您可以准确地遵循这个过程,并使故障排除变得容易。
也许能帮到别人。
数据文件示例:
Time,data1,data2,data2
08/11/2015 07:30:16,602,0.009,321
下面是代码:
$(document).ready(function() {
// AJAX in the data file
$.ajax({
type: "GET",
url: "data.csv",
dataType: "text",
success: function(data) {processData(data);}
});
// Let's process the data from the data file
function processData(data) {
var lines = data.split(/\r\n|\n/);
//Set up the data arrays
var time = [];
var data1 = [];
var data2 = [];
var data3 = [];
var headings = lines[0].split(','); // Splice up the first row to get the headings
for (var j=1; j<lines.length; j++) {
var values = lines[j].split(','); // Split up the comma seperated values
// We read the key,1st, 2nd and 3rd rows
time.push(values[0]); // Read in as string
// Recommended to read in as float, since we'll be doing some operations on this later.
data1.push(parseFloat(values[1]));
data2.push(parseFloat(values[2]));
data3.push(parseFloat(values[3]));
}
// For display
var x= 0;
console.log(headings[0]+" : "+time[x]+headings[1]+" : "+data1[x]+headings[2]+" : "+data2[x]+headings[4]+" : "+data2[x]);
}
})
希望这对将来的人有所帮助!
这是一个老问题,在2022年,有很多方法可以实现这一目标。首先,我认为D3是数据操作的最佳替代品之一。它是开源的,可以免费使用,但它也是模块化的,所以我们可以只导入fetch模块。
这里有一个基本的例子。我们将使用遗留模式,所以我将导入整个D3库。现在调用d3。csv函数,就完成了。该函数在内部调用fetch方法,因此它可以打开dataURL、url、files、blob等。
const fileInput = document.getElementById('csv')
const outElement = document.getElementById('out')
const previewCSVData = async dataurl => {
const d = await d3.csv(dataurl)
console.log({
d
})
outElement.textContent = d.columns
}
const readFile = e => {
const file = fileInput.files[0]
const reader = new FileReader()
reader.onload = () => {
const dataUrl = reader.result;
previewCSVData(dataUrl)
}
reader.readAsDataURL(file)
}
fileInput.onchange = readFile
<script type="text/javascript" src="https://unpkg.com/d3@7.6.1/dist/d3.min.js"></script>
<div>
<p>Select local CSV File:</p>
<input id="csv" type="file" accept=".csv">
</div>
<pre id="out"><p>File headers will appear here</p></pre>
If we don't want to use any library and we just want to use pain JavaScrip (Vanilla JS) and we managed to get the text content of a file as data and we don't want to use d3 we can implement a simple function that will split the data into a text array then we will extract the first line and split into a headers array and the rest of the text will be the lines we will process. After, we map each line and extract its values and create a row object from an array created from mapping each header to its correspondent value from values[index].
注意:
We also we going to use a little trick array objects in JavaScript can also have attributes. Yes so we will define an attribute rows.headers and assign the headers to it.
const data = `heading_1,heading_2,heading_3,heading_4,heading_5
value_1_1,value_2_1,value_3_1,value_4_1,value_5_1
value_1_2,value_2_2,value_3_2,value_4_2,value_5_2
value_1_3,value_2_3,value_3_3,value_4_3,value_5_3`
const csvParser = data => {
const text = data.split(/\r\n|\n/)
const [first, ...lines] = text
const headers = first.split(',')
const rows = []
rows.headers = headers
lines.map(line => {
const values = line.split(',')
const row = Object.fromEntries(headers.map((header, i) => [header, values[i]]))
rows.push(row)
})
return rows
}
const d = csvParser(data)
// Accessing to the theaders attribute
const headers = d.headers
console.log({headers})
console.log({d})
最后,让我们使用获取和解析csv文件来实现一个普通的JS文件加载器。
const fetchFile = async dataURL => {
return await fetch(dataURL).then(response => response.text())
}
const csvParser = data => {
const text = data.split(/\r\n|\n/)
const [first, ...lines] = text
const headers = first.split(',')
const rows = []
rows.headers = headers
lines.map(line => {
const values = line.split(',')
const row = Object.fromEntries(headers.map((header, i) => [header, values[i]]))
rows.push(row)
})
return rows
}
const fileInput = document.getElementById('csv')
const outElement = document.getElementById('out')
const previewCSVData = async dataURL => {
const data = await fetchFile(dataURL)
const d = csvParser(data)
console.log({ d })
outElement.textContent = d.headers
}
const readFile = e => {
const file = fileInput.files[0]
const reader = new FileReader()
reader.onload = () => {
const dataURL = reader.result;
previewCSVData(dataURL)
}
reader.readAsDataURL(file)
}
fileInput.onchange = readFile
<script type="text/javascript" src="https://unpkg.com/d3@7.6.1/dist/d3.min.js"></script>
<div>
<p>Select local CSV File:</p>
<input id="csv" type="file" accept=".csv">
</div>
<pre id="out"><p>File contents will appear here</p></pre>
我用这个文件进行了测试
有点晚了,但我希望这能帮助到一些人。
前段时间,我甚至遇到了一个问题,其中字符串数据包含\n在读取文件时,它用于读取不同的行。
Eg.
"Harry\nPotter","21","Gryffindor"
在阅读:
Harry
Potter,21,Gryffindor
我在我的angular项目中使用了一个csvtojson库来解决这个问题。
您可以使用以下代码将CSV文件读取为字符串,然后将该字符串传递给csvtojson库,它将为您提供一个JSON列表。
示例代码:
const csv = require('csvtojson');
if (files && files.length > 0) {
const file: File = files.item(0);
const reader: FileReader = new FileReader();
reader.readAsText(file);
reader.onload = (e) => {
const csvs: string = reader.result as string;
csv({
output: "json",
noheader: false
}).fromString(csvs)
.preFileLine((fileLine, idx) => {
//Convert csv header row to lowercase before parse csv file to json
if (idx === 0) { return fileLine.toLowerCase() }
return fileLine;
})
.then((result) => {
// list of json in result
});
}
}
下面是一个JavaScript函数,用于解析CSV数据,计算引号内的逗号。
// Parse a CSV row, accounting for commas inside quotes
function parse(row){
var insideQuote = false,
entries = [],
entry = [];
row.split('').forEach(function (character) {
if(character === '"') {
insideQuote = !insideQuote;
} else {
if(character == "," && !insideQuote) {
entries.push(entry.join(''));
entry = [];
} else {
entry.push(character);
}
}
});
entries.push(entry.join(''));
return entries;
}
函数解析CSV文件的示例如下:
"foo, the column",bar
2,3
"4, the value",5
数组:
// csv could contain the content read from a csv file
var csv = '"foo, the column",bar\n2,3\n"4, the value",5',
// Split the input into lines
lines = csv.split('\n'),
// Extract column names from the first line
columnNamesLine = lines[0],
columnNames = parse(columnNamesLine),
// Extract data from subsequent lines
dataLines = lines.slice(1),
data = dataLines.map(parse);
// Prints ["foo, the column","bar"]
console.log(JSON.stringify(columnNames));
// Prints [["2","3"],["4, the value","5"]]
console.log(JSON.stringify(data));
下面是如何将数据转换为对象,就像D3的csv解析器(这是一个可靠的第三方解决方案):
var dataObjects = data.map(function (arr) {
var dataObject = {};
columnNames.forEach(function(columnName, i){
dataObject[columnName] = arr[i];
});
return dataObject;
});
// Prints [{"foo":"2","bar":"3"},{"foo":"4","bar":"5"}]
console.log(JSON.stringify(dataObjects));
这是这段代码的工作原理。
享受吧!——伦
不要用逗号分隔——这对大多数CSV文件都不起作用,而且这个问题的视图太多了,提问者的输入数据不可能适用于所有人。解析CSV有点可怕,因为没有真正的官方标准,而且许多带分隔符的文本编写者不考虑边界情况。
这个问题很老了,但我相信现在有了更好的解决方案Papa Parse。它是我在贡献者的帮助下编写的一个库,用于解析CSV文本或文件。它是我所知道的唯一支持千兆字节大小文件的JS库。它还能优雅地处理畸形输入。
1分钟解析1gb文件
(更新:使用Papa Parse 4,同样的文件在Firefox中只花了大约30秒。Papa Parse 4是目前已知的最快的浏览器CSV解析器。)
解析文本非常简单:
var data = Papa.parse(csvString);
解析文件也很简单:
Papa.parse(file, {
complete: function(results) {
console.log(results);
}
});
流文件是类似的(这里是一个流远程文件的例子):
Papa.parse("http://example.com/bigfoo.csv", {
download: true,
step: function(row) {
console.log("Row:", row.data);
},
complete: function() {
console.log("All done!");
}
});
如果你的网页在解析过程中锁定,Papa可以使用网络工作者来保持你的网站反应性。
如果存在标题行,Papa可以自动检测分隔符并将值与标题列匹配。它还可以将数值转换为实际的数字类型。它可以适当地解析换行符、引号和其他奇怪的情况,甚至可以尽可能健壮地处理畸形输入。我从现有的库中汲取灵感来制作Papa,所以支持其他JS实现。