我正在尝试使用 JavaScript 读取存储在 csv 文件中的数据并将其呈现在表格中。 csv数据(逗号分隔)是(我将其缩小为比实际小得多):
Number, PDF1, PDF2, PDF3
0,,,
1,1.pdf,,
2,2a.pdf,2b.pdf,
3,3a.pdf,3b.pdf,3c.pdf
csv 中的单元格与在线单元格之间的对应关系是 1 比 1,除了最后 3 列 (PDF1/2/3)。我需要它们作为链接出现在同一单元格(每行)中,并以空格分隔。也就是说,不再有 3 列 PDF1/2/3,只有一列称为 PDF,其中包含 pdf 1、2 和 3(如果存在)的链接。所需的输出是:
| Number | PDF |
| 0 | |
| 1 | [link>1.pdf] |
| 2 | [link>2a.pdf] [link>2b.pdf] |
| 3 | [link>3a.pdf] [link>3b.pdf] [link>3c.pdf]|
到目前为止我所拥有的:
html:
<span id="output"></span>
JS:
async function fetchCSV(url) {
try {
const response = await fetch(url);
const data = await response.text();
document.getElementById('output').innerText = data;
processData(data);
} catch (error) {
console.error('Error fetching CSV:', error);
}
}
//Link to csv file
fetchCSV('https://blabla/myfile.csv');
//read csv and save contents to variable "lines"
function processData(csv){
var allTextLines = csv.split(/\r\n|\n/);
var lines = [];
var keys = allTextLines.shift().split(','); //first line (headers) of csv
while (allTextLines.length) {
var arr = allTextLines.shift().split(',');
var obj = {};
for(var i = 0; i < keys.length; i++){
obj[keys[i]] = arr[i];
}
lines.push(obj);
}
console.log(lines);
drawOutput(lines);
}
//draw table function drawOutput(lines){
//clear previous data
document.getElementById("output").innerHTML = "";
var table = document.createElement("table");
//first row (cols names) with "th"
var tableHeader = table.insertRow(-1);
Object.keys(lines[0]).forEach(function(key){
if (key == "PDF1") {} //don't show "PDF1" column
else if (key == "PDF2") {} //don't show "PDF2" column
else {
var el = document.createElement("TH");
if (key == "PDF3") {el.innerHTML = "PDF";} //show "PDF3" column as "PDF"
else {el.innerHTML = key;}
tableHeader.appendChild(el);
}
});
//the data (rest of the table)
for (var i = 0; i < lines.length-1; i++) {
var row = table.insertRow(-1);
Object.keys(lines[0]).forEach(function(key){
if (key == "PDF1") {var pdflink1 = lines[i][key];}
else if (key == "PDF2") {var pdflink2 = lines[i][key];}
else if (key == "PDF3") {var pdflink3 = lines[i][key];
var data = row.insertCell(-1);
if (pdflink1 != []) {
var a1 = document.createElement('a');
a1.innerHTML = 'pdf1 ';
a1.href = "dir/" + pdflink1;
data.appendChild(a1);
}
if (pdflink2 != []) {
var a2 = document.createElement('a');
a2.innerHTML = 'pdf2 ';
a2.href = "dir/" + pdflink2;
data.appendChild(a2);
}
if (pdflink3 != []) {
var a3 = document.createElement('a');
a3.innerHTML = 'pdf3';
a3.href = "dir/" + pdflink3;
data.appendChild(a3);}
}
else {
var data = row.insertCell(-1);
data.appendChild(document.createTextNode(lines[i][key]));
}});
}
document.getElementById("output").appendChild(table);
}
一切似乎都工作正常,但当 key ==“PDF3”为 true 时,我正在努力“保留”pdflink1 和 pdflink2 中的 pdf 名称,以便将它们与 pdflink3 放在一起。在这三个中,只有后者在输出中按需要呈现:
| Number | PDF |
| 0 | |
| 1 | [dir/undefined] |
| 2 | [dir/undefined] [dir/undefined] |
| 3 | [dir/undefined] [dir/undefined] [dir/3c.pdf]|
我感谢任何帮助。谢谢你。
有一些问题。 键名中的前导空格导致了问题。可使用
.trim()
修复
pdflink1、pdflink2、pdflink3 需要移到
forEach()
循环之外,以便它们的值在迭代之间可用。
您有两个相互冲突的
var data
声明。我把第二个改成了let
。我实际上建议您将所有 var
声明更改为 let
。
在代码片段中查找编辑注释以了解具体更改。
//Link to csv file
// EDIT Changed just for the snippet demo
// fetchCSV('https://blabla/myfile.csv');
async function fetchCSV(url) {
try {
const response = await fetch(url);
const data = await response.text();
document.getElementById('output').innerText = data;
processData(data);
} catch (error) {
console.error('Error fetching CSV:', error);
}
}
//read csv and save contents to variable "lines"
function processData(csv){
var allTextLines = csv.split(/\r\n|\n/);
var lines = [];
var keys = allTextLines.shift().split(','); //first line (headers) of csv
while (allTextLines.length) {
var arr = allTextLines.shift().split(',');
var obj = {};
for(var i = 0; i < keys.length; i++){
// EDIT Leading spaces were causing problems.
// obj key names had a leading space, causing many problems later on with comparisons
obj[keys[i].trim()] = arr[i];
}
lines.push(obj);
}
// console.log(lines);
drawOutput(lines);
}
//draw table
function drawOutput(lines){
//clear previous data
document.getElementById("output").innerHTML = "";
var table = document.createElement("table");
//first row (cols names) with "th"
var tableHeader = table.insertRow(-1);
Object.keys(lines[0]).forEach(function(key){
if (key == "PDF1") {} //don't show "PDF1" column
else if (key == "PDF2") {} //don't show "PDF2" column
else {
var el = document.createElement("TH");
if (key == "PDF3") {el.innerHTML = "PDF";} //show "PDF3" column as "PDF"
else {el.innerHTML = key;}
tableHeader.appendChild(el);
}
});
//the data (rest of the table)
for (var i = 0; i < lines.length-1; i++) {
var row = table.insertRow(-1);
// EDIT Need to move these declaritions outside the for loop
var pdflink1 = ""
var pdflink2 = ""
var pdflink3 = ""
Object.keys(lines[0]).forEach( function(key) {
if (key == "PDF1") {
pdflink1 = lines[i][key];
}
else if (key == "PDF2") {
pdflink2 = lines[i][key];
}
else if (key == "PDF3") {
pdflink3 = lines[i][key];
var data = row.insertCell(-1);
if (pdflink1 != []) {
var a1 = document.createElement('a');
a1.innerHTML = 'pdf1 ';
a1.href = "dir/" + pdflink1;
data.appendChild(a1);
}
if (pdflink2 != []) {
var a2 = document.createElement('a');
a2.innerHTML = 'pdf2 ';
a2.href = "dir/" + pdflink2;
data.appendChild(a2);
}
if (pdflink3 != []) {
var a3 = document.createElement('a');
a3.innerHTML = 'pdf3';
a3.href = "dir/" + pdflink3;
data.appendChild(a3);}
}
else {
// EDIT You had two conflicting var data declarations
let data = row.insertCell(-1);
data.appendChild( document.createTextNode(lines[i][key]) );
}
});
}
document.getElementById("output").appendChild(table);
}
// EDIT Added just for the snippet demo
let csvData = `Number, PDF1, PDF2, PDF3
0,,,
1,1.pdf,,
2,2a.pdf,2b.pdf,
3,3a.pdf,3b.pdf,3c.pdf
`
// EDIT Added these two lines to use instead of fetchCSV(), just for the snippet demo
document.getElementById('output').innerText = csvData;
processData(csvData);
/* EDIT For visualization */
table {
background-color: gray;
border-collapse: collapse;
margin: 10px;
border: solid 2px black;
box-shadow: 4px 4px 10px black;
}
th {
padding: 0.5rem 1rem;
border-bottom: solid 1px black;
}
td {
padding-left: 1rem;
padding-bottom: 0.5rem;
}
th, td {
border-right: solid 1px black;
}
td a {
margin-right: 1rem;
}
<span id="output"></span>