代码之家  ›  专栏  ›  技术社区  ›  nicholaswmin

从HTML表下载CSV

  •  1
  • nicholaswmin  · 技术社区  · 6 年前


    如何下载HTML <table> 作为浏览器中的CSV?假设HTML表在实际数据中不包含逗号。

    <table style="width:100%">
      <tr>
        <th>Firstname</th>
        <th>Lastname</th> 
        <th>Age</th>
      </tr>
      <tr>
        <td>Jill</td>
        <td>Smith</td> 
        <td>50</td>
      </tr>
      <tr>
        <td>Eve</td>
        <td>Jackson</td> 
        <td>94</td>
      </tr>
    </table>
    

    我不关心旧的浏览器,只关心完全支持ES6的现代浏览器。

    2 回复  |  直到 6 年前
        1
  •  1
  •   nicholaswmin    6 年前

    只是在HTML行上循环 tr ,用逗号连接列 , 使用换行符的行 /n

    然后在HTML头上循环 th ,用逗号连接每个 .

    然后使用换行符连接头字符串和行字符串 /n个 .

    从那时起只要创建一个超链接 <a> Blob 你的CSV字符串和力 .click()

    下面是一个在Chrome 68、FF 58、MacOS Safari 11上运行良好的示例:

    const tableToCSV = table => {
      const headers = Array.from(table.querySelectorAll('th'))
        .map(item => item.innerText).join(',')
    
      const rows = Array.from(table.querySelectorAll('tr'))
        .reduce((arr, domRow) => {
          if (domRow.querySelector('th')) return arr
    
          const cells = Array.from(domRow.querySelectorAll('td'))
            .map(item => item.innerText)
            .join(',')
    
          return arr.concat([cells])
        }, [])
    
      return headers + '\n' + rows.join('\n')
    }
    
    const downloadCSV = csv => {
      const csvFile = new Blob([csv], { type: 'text/csv' })
      const downloadLink =  document.createElement('a')
    
      downloadLink.download = `CSV-${new Date().toDateString()}.csv`
      downloadLink.href = window.URL.createObjectURL(csvFile)
      downloadLink.style.display = 'none'
      document.body.appendChild(downloadLink)
    
      downloadLink.click()
    }
    
    document.querySelector('button').addEventListener('click', () => {
      const table = document.querySelector('table')
      const csv = tableToCSV(table)
      
      return downloadCSV(csv)
    })
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
    }
    
    th, td {
      padding: 15px;
      text-align: left;
    }
    
    table#t01 {
      width: 100%;    
      background-color: #f1f1c1;
    }
    <table style="width:100%">
      <tr>
        <th>Firstname</th>
        <th>Lastname</th> 
        <th>Age</th>
      </tr>
      <tr>
        <td>Jill</td>
        <td>Smith</td> 
        <td>50</td>
      </tr>
      <tr>
        <td>Eve</td>
        <td>Jackson</td> 
        <td>94</td>
      </tr>
    </table>
    
    <button on-click="download()">Download CSV</button>
        2
  •  0
  •   Roger Perez    6 年前

    反应 需要下载csv文件的文件。

    我的文件里有一个跨度标签。为大多数函数/方法的功能添加了注释。

    import { tableToCSV, downloadCSV } from './../Helpers/exportToCSV';
    
    
    export function tableToCSV(){
      let tableHeaders = Array.from(document.querySelectorAll('th'))
        .map(item => {
          // title = splits elem tags on '\n',
          // then filter out blank "" that appears in array.
          // ex ["Timestamp", "[Full time]", ""]
          let title = item.innerText.split("\n").filter(str => (str !== 0)).join(" ")
          return title
        }).join(",")
    
      const rows = Array.from(document.querySelectorAll('tr'))
      .reduce((arr, currRow) => {
        // if tr tag contains th tag.
        // if null return array.
        if (currRow.querySelector('th')) return arr
    
        // concats individual cells into csv format row.
        const cells = Array.from(currRow.querySelectorAll('td'))
          .map(item => item.innerText)
          .join(',')
        return arr.concat([cells])
      }, [])
    
    return tableHeaders + '\n' + rows.join('\n')
    }
    
    export function downloadCSV(csv){
      const csvFile = new Blob([csv], { type: 'text/csv' })
      const downloadLink =  document.createElement('a')
      // sets the name for the download file
      downloadLink.download = `CSV-${currentDateUSWritten()}.csv`
      // sets the url to the window URL created from csv file above
      downloadLink.href = window.URL.createObjectURL(csvFile)
      // creates link, but does not display it.
      downloadLink.style.display = 'none'
      // add link to body so click function below works
      document.body.appendChild(downloadLink)
    
      downloadLink.click()
    }
    

    当用户点击export to csv时,它会触发react中的以下函数。

      handleExport = (e) => {
        e.preventDefault();
        const csv = tableToCSV()
        return downloadCSV(csv)
      }
    

      <table id="datatable">
            <tbody>
              <tr id="tableHeader" className="t-header">
                <th>Timestamp
                  <span className="block">full time</span></th>
                <th>current rate
                  <span className="block">alt view</span>
                </th>
                <th>Battery Voltage
                  <span className="block">current voltage
                  </span>
                </th>
                <th>Temperature 1
                  <span className="block">[C]</span>
                </th>
                <th>Temperature 2
                  <span className="block">[C]</span>
                </th>
                <th>Time & Date </th>
              </tr>
    
            </tbody>
            <tbody>
              {this.renderData()}
            </tbody>
          </table>
        </div>