【问题标题】:Copy paste from excel, difference between line break in cell and row delimiter从excel复制粘贴,单元格中的换行符和行分隔符之间的区别
【发布时间】:2021-05-31 12:11:06
【问题描述】:

我们需要向我们的客户提供一种将 Excel 复制粘贴到 Web 应用程序中的表格的方法。 我们用换行符分割行,用制表符分割列。

问题是在单个单元格中可以有换行符,所以split(\n) 会简单地理解有一个新行。

    const rows = event.target.value.split('\n');
    for (let row of rows) {
      const values = row.split('\t');
    }

使用上面的代码,当单元格中没有换行符时,我们可以得到一个很好的复制粘贴表格,但是一旦单元格中有换行符,所有内容都会移动到一行并打破所有内容。

如何区分用于分隔行的换行符和单元格中的换行符?

【问题讨论】:

    标签: javascript excel csv


    【解决方案1】:

    考虑我将 Excel 数据复制粘贴到 Notepad++ 的小示例,我们可以看到 cat\nfish 被引用:

    因此,您可以将粘贴到 Web 应用程序的内容视为制表符分隔值 (tsv) 并对其进行解析。

    在下面的 sn-p 中,tsvStringToArray 改编自 here(也请参见 here)。请注意,由于dog 之后的最后CR LF,因此返回了额外的行。在现实生活中,您可能应该寻找一个库来为您执行此操作。您可能会将 D3 视为可以在浏览器中运行的东西。

    对于arrToTable,我认为你必须有更好的努力arrToTable。但是,您应该考虑是否需要在 HTML 中重新创建换行符。

    const target = document.getElementById("input");
    const output = document.getElementById("output");
    
    const tsvStringToArray = (data) => {
      const re = /(\t|\r?\n|\r|^)(?:"([^"]*(?:""[^"]*)*)"|([^\t\r\n]*))/gi
      const result = [[]]
      let matches
      while ((matches = re.exec(data))) {
        if (matches[1].length && matches[1] !== "\t") result.push([])
        result[result.length - 1].push(
          matches[2] !== undefined ? matches[2].replace(/""/g, '"') : matches[3]
        )
      }
      //console.log(result);
      return result
    }
    
    const arrToTable = arr => {
      let tbl = document.createElement("table");
      for (row of arr) {
        let tr = document.createElement("tr");
        for (cell of row) {
          let td = document.createElement("td");
          let test = /\n/.test(cell);
          if (test) {
            let items = cell.split(/\n/);
            for ([idx, item] of items.entries()) {
              td.appendChild(document.createTextNode(item));
              if (idx < items.length) {
                td.appendChild(document.createElement("br"));
              }
            }
          } else {
            td.appendChild(document.createTextNode(cell));    
          }
          tr.appendChild(td);
        }
        tbl.appendChild(tr);
      }
      return tbl;
    }
    
    target.addEventListener("paste", e => {
      const text = event.clipboardData.getData("text");
      const arr = tsvStringToArray(text).slice(0, -1);
      const el = arrToTable(arr);
      output.appendChild(el);
    });
    div#input {
      height: 90px;
      width: 320px;
      background-color: powderblue;
    }
    
    table, tr, td {
      border: 1px solid black;
    }
    Paste in blue box:
    <div id="input" contenteditable="true"></div>
    <p>
    <div id="output"></div>

    【讨论】:

      猜你喜欢
      • 2021-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      相关资源
      最近更新 更多