这是一个自我解答的问题。
如何在浏览器中以CSV格式下载HTML <table>
?假设HTML表格的实际数据中没有逗号。
这是我的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的现代浏览器。
答案 0 :(得分:1)
只需循环遍历HTML行tr
,用逗号,
将各列连接起来,并使用换行符/n
将各行连接起来。
然后在HTML标头th
上循环,并用逗号,
将每个标头连接起来。
然后使用换行符/n
连接标题字符串和行字符串。
从那时起,只需使用包含<a>
组CSV字符串的超链接Blob
并强制.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>
答案 1 :(得分:0)
使用上面的答案,但根据我的需要进行了更改。我使用了以下功能,并将其导入到需要下载csv文件的 REACT 文件中。
我的th个文件中有一个span标签。添加了对大多数功能/方法的注释。
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()
}
当用户单击导出到csv时,它会在react中触发以下功能。
handleExport = (e) => {
e.preventDefault();
const csv = tableToCSV()
return downloadCSV(csv)
}
示例html表元素。
<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>