合并表格中不同单元格的数据

问题描述 投票:0回答:1

我正在尝试使用 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]|

我感谢任何帮助。谢谢你。

javascript html
1个回答
0
投票

有一些问题。 键名中的前导空格导致了问题。可使用

.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>

© www.soinside.com 2019 - 2024. All rights reserved.