jquery 使用vanilla JavaScript将HTML表格导出为CSV

tjrkku2a  于 2023-11-17  发布在  jQuery
关注(0)|答案(9)|浏览(194)

我试图在我的网站中添加CSV下载选项的功能。它应该将网站中存在的HTML表转换为CSV内容并使其可下载。我一直在通过互联网搜索一个很好的插件,并找到了一些有用的,如http://www.dev-skills.com/export-html-table-to-csv-file/,但它使用PHP脚本来做下载部分。我想知道是否有一个纯JavaScript库可以使用服务器端做此功能像node.js这样的软件不使用php??

70gysomp

70gysomp1#

应该可以在每个现代浏览器上工作,没有jQuery或任何依赖,这里是我的实现:

  1. // Quick and simple export target #table_id into a csv
  2. function download_table_as_csv(table_id, separator = ',') {
  3. // Select rows from table_id
  4. var rows = document.querySelectorAll('table#' + table_id + ' tr');
  5. // Construct csv
  6. var csv = [];
  7. for (var i = 0; i < rows.length; i++) {
  8. var row = [], cols = rows[i].querySelectorAll('td, th');
  9. for (var j = 0; j < cols.length; j++) {
  10. // Clean innertext to remove multiple spaces and jumpline (break csv)
  11. var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ')
  12. // Escape double-quote with double-double-quote (see https://stackoverflow.com/questions/17808511/properly-escape-a-double-quote-in-csv)
  13. data = data.replace(/"/g, '""');
  14. // Push escaped string
  15. row.push('"' + data + '"');
  16. }
  17. csv.push(row.join(separator));
  18. }
  19. var csv_string = csv.join('\n');
  20. // Download it
  21. var filename = 'export_' + table_id + '_' + new Date().toLocaleDateString() + '.csv';
  22. var link = document.createElement('a');
  23. link.style.display = 'none';
  24. link.setAttribute('target', '_blank');
  25. link.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv_string));
  26. link.setAttribute('download', filename);
  27. document.body.appendChild(link);
  28. link.click();
  29. document.body.removeChild(link);
  30. }

字符串
然后添加您的下载按钮/链接:

  1. <a href="#" onclick="download_table_as_csv('my_id_table_to_export');">Download as CSV</a>


CSV文件是定时的,与默认的Excel格式兼容。

  • 评论后更新 *:添加了第二个参数“separator”,它可以用来配置另一个字符,如;,如果您有用户在世界不同地区下载您的csv,这是有用的,因为他们可以使用Excel的另一个默认分隔符,有关更多信息,请参阅:https://superuser.com/a/606274/908273
展开查看全部
egmofgnx

egmofgnx2#

只使用jQuery、vanilla Javascripttable2CSV库:
export-to-html-table-as-csv-file-using-jquery
将此代码放入要在head部分加载的脚本中:

  1. $(document).ready(function () {
  2. $('table').each(function () {
  3. var $table = $(this);
  4. var $button = $("<button type='button'>");
  5. $button.text("Export to spreadsheet");
  6. $button.insertAfter($table);
  7. $button.click(function () {
  8. var csv = $table.table2CSV({
  9. delivery: 'value'
  10. });
  11. window.location.href = 'data:text/csv;charset=UTF-8,'
  12. + encodeURIComponent(csv);
  13. });
  14. });
  15. })

字符串
备注:
需要jQuerytable2CSV:在上面的脚本之前添加对这两个库的脚本引用。
table选择器用作示例,可以根据您的需要进行调整。
它只适用于完全支持Data URI的浏览器:Firefox,Chrome和Opera,而不适用于IE,IE只支持Data URIs将二进制图像数据嵌入到页面中。
为了完全兼容浏览器,您必须使用稍微不同的方法,需要服务器端脚本来echo CSV。

展开查看全部
nwsw7zdq

nwsw7zdq3#

http://jordiburgos.com/post/2014/excellentexport-javascript-export-to-excel-csv.html上有一个非常简单的免费开源解决方案
首先从https://github.com/jmaister/excellentexport/releases/tag/v1.4下载JavaScript文件和示例文件
HTML页面看起来像下面。
确保JavaScript文件在同一个文件夹中,或者相应地更改html文件中脚本的路径。

  1. <html>
  2. <head>
  3. <title>Export to excel test</title>
  4. <script src="excellentexport.js"></script>
  5. <style>
  6. table, tr, td {
  7. border: 1px black solid;
  8. }
  9. </style>
  10. </head>
  11. <body>
  12. <h1>ExcellentExport.js</h1>
  13. Check on <a href="http://jordiburgos.com">jordiburgos.com</a> and <a href="https://github.com/jmaister/excellentexport">GitHub</a>.
  14. <h3>Test page</h3>
  15. <br/>
  16. <a download="somedata.xls" href="#" onclick="return ExcellentExport.excel(this, 'datatable', 'Sheet Name Here');">Export to Excel</a>
  17. <br/>
  18. <a download="somedata.csv" href="#" onclick="return ExcellentExport.csv(this, 'datatable');">Export to CSV</a>
  19. <br/>
  20. <table id="datatable">
  21. <tr>
  22. <th>Column 1</th>
  23. <th>Column "cool" 2</th>
  24. <th>Column 3</th>
  25. </tr>
  26. <tr>
  27. <td>100,111</td>
  28. <td>200</td>
  29. <td>300</td>
  30. </tr>
  31. <tr>
  32. <td>400</td>
  33. <td>500</td>
  34. <td>600</td>
  35. </tr>
  36. <tr>
  37. <td>Text</td>
  38. <td>More text</td>
  39. <td>Text with
  40. new line</td>
  41. </tr>
  42. </table>
  43. </body>

字符串
这是非常容易使用,因为我已经尝试了大多数其他方法。

展开查看全部
kkih6yb8

kkih6yb84#

在服务器端不需要PHP脚本。只在客户端,在接受Data URIs的浏览器中这样做:

  1. data:application/csv;charset=utf-8,content_encoded_as_url

字符串
数据URI将类似于:

  1. data:application/csv;charset=utf-8,Col1%2CCol2%2CCol3%0AVal1%2CVal2%2CVal3%0AVal11%2CVal22%2CVal33%0AVal111%2CVal222%2CVal333


您可以通过以下方式调用此URI:

  • 使用window.open
  • 或设置window.location
  • 或通过锚的href
  • 通过添加下载属性,它将在Chrome中工作,仍然必须在IE中测试。

要进行测试,只需复制上面的URI并粘贴到浏览器地址栏中。或者在HTML页面中测试下面的锚:

  1. <a download="somedata.csv" href="data:application/csv;charset=utf-8,Col1%2CCol2%2CCol3%0AVal1%2CVal2%2CVal3%0AVal11%2CVal22%2CVal33%0AVal111%2CVal222%2CVal333">Example</a>


要创建内容,从表中获取值,您可以使用MelanciaUK提到的table2CSV并执行:

  1. var csv = $table.table2CSV({delivery:'value'});
  2. window.location.href = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(csv);

展开查看全部
yuvru6vn

yuvru6vn5#

(1)这是针对此问题的原生JavaScript解决方案。它适用于大多数现代浏览器。

  1. function export2csv() {
  2. let data = "";
  3. const tableData = [];
  4. const rows = document.querySelectorAll("table tr");
  5. for (const row of rows) {
  6. const rowData = [];
  7. for (const [index, column] of row.querySelectorAll("th, td").entries()) {
  8. // To retain the commas in the "Description" column, we can enclose those fields in quotation marks.
  9. if ((index + 1) % 3 === 0) {
  10. rowData.push('"' + column.innerText + '"');
  11. } else {
  12. rowData.push(column.innerText);
  13. }
  14. }
  15. tableData.push(rowData.join(","));
  16. }
  17. data += tableData.join("\n");
  18. const a = document.createElement("a");
  19. a.href = URL.createObjectURL(new Blob([data], { type: "text/csv" }));
  20. a.setAttribute("download", "data.csv");
  21. document.body.appendChild(a);
  22. a.click();
  23. document.body.removeChild(a);
  24. }
  1. table {
  2. border-collapse: collapse;
  3. }
  4. td, th {
  5. border: 1px solid #aaa;
  6. padding: 0.5rem;
  7. text-align: left;
  8. }
  9. td {
  10. font-size: 0.875rem;
  11. }
  12. .btn-group {
  13. padding: 1rem 0;
  14. }
  15. button {
  16. background-color: #fff;
  17. border: 1px solid #000;
  18. margin-top: 0.5rem;
  19. border-radius: 3px;
  20. padding: 0.5rem 1rem;
  21. font-size: 1rem;
  22. }
  23. button:hover {
  24. cursor: pointer;
  25. background-color: #000;
  26. color: #fff;
  27. }
  1. <table>
  2. <thead>
  3. <tr>
  4. <th>Name</th>
  5. <th>Author</th>
  6. <th>Description</th>
  7. </tr>
  8. </thead>
  9. <tbody>
  10. <tr>
  11. <td>jQuery</td>
  12. <td>John Resig</td>
  13. <td>The Write Less, Do More, JavaScript Library.</td>
  14. </tr>
  15. <tr>
  16. <td>React</td>
  17. <td>Jordan Walke</td>
  18. <td>React makes it painless to create interactive UIs.</td>
  19. </tr>
  20. <tr>
  21. <td>Vue.js</td>
  22. <td>Yuxi You</td>
  23. <td>The Progressive JavaScript Framework.</td>
  24. </tr>
  25. </tbody>
  26. </table>
  27. <div class="btn-group">
  28. <button onclick="export2csv()">csv</button>
  29. </div>

(2)如果你想要一个纯JavaScript库,FileSaver.js可以帮助你保存触发文件下载的代码片段。此外,FileSaver.js不会负责构建导出的内容。你必须自己构建你想要的格式的内容。

展开查看全部
vohkndzv

vohkndzv6#

现代解决方案

这里提出的大多数解决方案都将打破嵌套表或td元素中的其他元素。我经常在表中使用其他元素,但只想导出最顶层的表。我从Calumah中找到了一些代码,并添加了一些现代的ES6 JS。
使用textContent是比innerText更好的解决方案,因为innerText将返回td元素中的任何HTML。然而,即使textContent也会返回嵌套元素中的文本。更好的解决方案是在td上使用自定义数据属性,并从那里为CSV拉取值。
编码愉快!

  1. function downloadAsCSV(tableEle, separator = ','){
  2. let csvRows = []
  3. //only get direct children of the table in question (thead, tbody)
  4. Array.from(tableEle.children).forEach(function(node){
  5. //using scope to only get direct tr of node
  6. node.querySelectorAll(':scope > tr').forEach(function(tr){
  7. let csvLine = []
  8. //again scope to only get direct children
  9. tr.querySelectorAll(':scope > td').forEach(function(td){
  10. //clone as to not remove anything from original
  11. let copytd = td.cloneNode(true)
  12. let data
  13. if(copytd.dataset.val) data = copytd.dataset.val.replace(/(\r\n|\n|\r)/gm, '')
  14. else {
  15. Array.from(copytd.children).forEach(function(remove){
  16. //remove nested elements before getting text
  17. remove.parentNode.removeChild(remove)
  18. })
  19. data = copytd.textContent.replace(/(\r\n|\n|\r)/gm, '')
  20. }
  21. data = data.replace(/(\s\s)/gm, ' ').replace(/"/g, '""')
  22. csvLine.push('"'+data+'"')
  23. })
  24. csvRows.push(csvLine.join(separator))
  25. })
  26. })
  27. var a = document.createElement("a")
  28. a.style = "display: none; visibility: hidden" //safari needs visibility hidden
  29. a.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csvRows.join('\n'))
  30. a.download = 'testfile.csv'
  31. document.body.appendChild(a)
  32. a.click()
  33. a.remove()
  34. }

字符串
编辑:cloneNode()更新为cloneNode(true)以获取内部信息

展开查看全部
hmtdttj4

hmtdttj47#

使用上面的答案,但根据我的需要进行了修改。
我使用以下函数并导入到我的REACT文件,在那里我需要下载csv文件。
我在th元素中有一个span标签。添加了大多数函数/方法的注解。

  1. import { tableToCSV, downloadCSV } from './../Helpers/exportToCSV';
  2. export function tableToCSV(){
  3. let tableHeaders = Array.from(document.querySelectorAll('th'))
  4. .map(item => {
  5. // title = splits elem tags on '\n',
  6. // then filter out blank "" that appears in array.
  7. // ex ["Timestamp", "[Full time]", ""]
  8. let title = item.innerText.split("\n").filter(str => (str !== 0)).join(" ")
  9. return title
  10. }).join(",")
  11. const rows = Array.from(document.querySelectorAll('tr'))
  12. .reduce((arr, currRow) => {
  13. // if tr tag contains th tag.
  14. // if null return array.
  15. if (currRow.querySelector('th')) return arr
  16. // concats individual cells into csv format row.
  17. const cells = Array.from(currRow.querySelectorAll('td'))
  18. .map(item => item.innerText)
  19. .join(',')
  20. return arr.concat([cells])
  21. }, [])
  22. return tableHeaders + '\n' + rows.join('\n')
  23. }
  24. export function downloadCSV(csv){
  25. const csvFile = new Blob([csv], { type: 'text/csv' })
  26. const downloadLink = document.createElement('a')
  27. // sets the name for the download file
  28. downloadLink.download = `CSV-${currentDateUSWritten()}.csv`
  29. // sets the url to the window URL created from csv file above
  30. downloadLink.href = window.URL.createObjectURL(csvFile)
  31. // creates link, but does not display it.
  32. downloadLink.style.display = 'none'
  33. // add link to body so click function below works
  34. document.body.appendChild(downloadLink)
  35. downloadLink.click()
  36. }

字符串
当用户点击导出到csv时,它会在react中触发以下函数。

  1. handleExport = (e) => {
  2. e.preventDefault();
  3. const csv = tableToCSV()
  4. return downloadCSV(csv)
  5. }


HTML表格元素示例。

  1. <table id="datatable">
  2. <tbody>
  3. <tr id="tableHeader" className="t-header">
  4. <th>Timestamp
  5. <span className="block">full time</span></th>
  6. <th>current rate
  7. <span className="block">alt view</span>
  8. </th>
  9. <th>Battery Voltage
  10. <span className="block">current voltage
  11. </span>
  12. </th>
  13. <th>Temperature 1
  14. <span className="block">[C]</span>
  15. </th>
  16. <th>Temperature 2
  17. <span className="block">[C]</span>
  18. </th>
  19. <th>Time & Date </th>
  20. </tr>
  21. </tbody>
  22. <tbody>
  23. {this.renderData()}
  24. </tbody>
  25. </table>
  26. </div>

展开查看全部
oogrdqng

oogrdqng8#

我发现有一个图书馆。请参阅这里的例子:
https://editor.datatables.net/examples/extensions/exportButtons.html
除了上面的代码外,还加载了以下JavaScript库文件以供本示例使用:
在HTML中,包含以下脚本:

  1. jquery.dataTables.min.js
  2. dataTables.editor.min.js
  3. dataTables.select.min.js
  4. dataTables.buttons.min.js
  5. jszip.min.js
  6. pdfmake.min.js
  7. vfs_fonts.js
  8. buttons.html5.min.js
  9. buttons.print.min.js

字符串
通过添加以下脚本来启用按钮:

  1. <script>
  2. $(document).ready( function () {
  3. $('#table-arrays').DataTable({
  4. dom: '<"top"Blf>rt<"bottom"ip>',
  5. buttons: ['copy', 'excel', 'csv', 'pdf', 'print'],
  6. select: true,
  7. });
  8. } );
  9. </script>


由于某种原因,Excel导出导致文件损坏,但可以修复。或者,禁用Excel并使用CSV导出。

展开查看全部
kxkpmulp

kxkpmulp9#

在我的例子中,我需要MOST的基本功能来抓取HTML表数据并将其转换为csv文件。没有一个值会有干扰字符,所以我不需要任何转义或编码考虑。我也不喜欢声明单用途变量,除非这些变量在表达它们所包含的数据方面很有价值。
我无法让下载机制在Stacksnippet中工作,但这里有一个工作的jsfiddle demo
my_report更改为目标表的id。“
my_scraped_report.csv更改为所需的下载文件的文件名。

  1. function exportToCSV() {
  2. // The following was inspired by https://stackoverflow.com/a/56370447/2943403
  3. const rows = document.querySelectorAll('table#my_report tr'),
  4. link = document.createElement('a');
  5. link.download = 'my_scraped_report.csv';
  6. link.href = URL.createObjectURL(
  7. new Blob(
  8. [
  9. Array.from(rows).map(row => {
  10. return Array.from(row.querySelectorAll('td, th')).map(col => col.innerText).join(',');
  11. }).join('\n')
  12. ],
  13. { type: 'text/plain' }
  14. )
  15. );
  16. link.click();
  17. }

字符串
嘲笑于飞:

  1. <button onclick="exportToCSV()" style="margin-bottom: 30px">CSV</button>
  2. <table id="my_report" border="1">
  3. <thead>
  4. <tr class="vertical-text" role="row">
  5. <th></th>
  6. <th>11/10/2023</th>
  7. <th>12/10/2023</th>
  8. <th>13/10/2023</th>
  9. </tr>
  10. </thead>
  11. <tbody>
  12. <tr>
  13. <td>One</td>
  14. <td class=" text-center">456</td>
  15. <td class=" text-center">298</td>
  16. <td class=" text-center">498</td>
  17. </tr>
  18. <tr>
  19. <td>Two</td>
  20. <td class=" text-center">123</td>
  21. <td class=" text-center">321</td>
  22. <td class=" text-center">466</td>
  23. </tr>
  24. <tr>
  25. <td>Three</td>
  26. <td class=" text-center">372</td>
  27. <td class=" text-center">193</td>
  28. <td class=" text-center">922</td>
  29. </tr>
  30. </tbody>
  31. </table>

展开查看全部

相关问题