바닐라 Javascript를 사용하여 HTML 테이블을 CSV로 내보내기
제 웹사이트에 csv 다운로드 옵션 기능을 추가하려고 합니다.그것은 웹사이트에 있는 html 테이블을 csv 콘텐츠로 변환하여 다운로드 할 수 있도록 해야 합니다.인터넷을 통해 좋은 플러그인을 검색해보니 http://www.dev-skills.com/export-html-table-to-csv-file/ 과 같은 유용한 플러그인을 찾았지만 다운로드 부분은 php 스크립트를 사용합니다.php?를 사용하지 않고 node.js와 같은 서버 측 소프트웨어를 사용하여 이 기능을 수행할 수 있는 순수 자바스크립트 라이브러리가 있는지 궁금합니다.
jQuery나 의존성 없이 모든 최신 브라우저에서 작동해야 하는 나의 구현은 다음과 같습니다.
// Quick and simple export target #table_id into a csv
function download_table_as_csv(table_id, separator = ',') {
// Select rows from table_id
var rows = document.querySelectorAll('table#' + table_id + ' tr');
// Construct csv
var csv = [];
for (var i = 0; i < rows.length; i++) {
var row = [], cols = rows[i].querySelectorAll('td, th');
for (var j = 0; j < cols.length; j++) {
// Clean innertext to remove multiple spaces and jumpline (break csv)
var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ')
// Escape double-quote with double-double-quote (see https://stackoverflow.com/questions/17808511/properly-escape-a-double-quote-in-csv)
data = data.replace(/"/g, '""');
// Push escaped string
row.push('"' + data + '"');
}
csv.push(row.join(separator));
}
var csv_string = csv.join('\n');
// Download it
var filename = 'export_' + table_id + '_' + new Date().toLocaleDateString() + '.csv';
var link = document.createElement('a');
link.style.display = 'none';
link.setAttribute('target', '_blank');
link.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv_string));
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
그런 다음 다운로드 버튼/링크를 추가합니다.
<a href="#" onclick="download_table_as_csv('my_id_table_to_export');">Download as CSV</a>
CSV 파일은 시간이 지정되어 있으며 기본 Excel 형식과 호환됩니다.
주석 후 업데이트:두 번째 매개 변수 "분리기"가 추가되었으며, 다음과 같은 다른 문자를 구성하는 데 사용할 수 있습니다.;사용자가 다른 지역에서 CSV를 다운로드하는 경우 유용합니다. 사용자가 Excel에 대해 다른 기본 구분 기호를 사용할 수 있기 때문입니다. 자세한 내용은 https://superuser.com/a/606274/908273 을 참조하십시오.
just 사용jQuery바닐라 맛의Javascript그리고table2CSV라이브러리:
데이터베이스 테이블로 내보내기-csv-file-using-jquery
이 코드를 로드할 스크립트에 넣습니다.head섹션:
$(document).ready(function () {
$('table').each(function () {
var $table = $(this);
var $button = $("<button type='button'>");
$button.text("Export to spreadsheet");
$button.insertAfter($table);
$button.click(function () {
var csv = $table.table2CSV({
delivery: 'value'
});
window.location.href = 'data:text/csv;charset=UTF-8,'
+ encodeURIComponent(csv);
});
});
})
주의:
jQuery 및 table2 필요CSV: 위의 스크립트 앞에 두 라이브러리에 스크립트 참조를 추가합니다.
그table선택기는 예로 사용되며 필요에 따라 조정할 수 있습니다.
전체 브라우저에서만 작동합니다.Data URI지원:IE가 아닌 Firefox, Chrome 및 Opera는 지원합니다.Data URIs이진 이미지 데이터를 페이지에 포함하는 데 사용됩니다.
전체 브라우저 호환성을 위해 서버 사이드 스크립트가 필요한 약간 다른 접근 방식을 사용해야 합니다.echoCSV
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 파일의 스크립트 경로를 적절하게 변경합니다.
<html>
<head>
<title>Export to excel test</title>
<script src="excellentexport.js"></script>
<style>
table, tr, td {
border: 1px black solid;
}
</style>
</head>
<body>
<h1>ExcellentExport.js</h1>
Check on <a href="http://jordiburgos.com">jordiburgos.com</a> and <a href="https://github.com/jmaister/excellentexport">GitHub</a>.
<h3>Test page</h3>
<br/>
<a download="somedata.xls" href="#" onclick="return ExcellentExport.excel(this, 'datatable', 'Sheet Name Here');">Export to Excel</a>
<br/>
<a download="somedata.csv" href="#" onclick="return ExcellentExport.csv(this, 'datatable');">Export to CSV</a>
<br/>
<table id="datatable">
<tr>
<th>Column 1</th>
<th>Column "cool" 2</th>
<th>Column 3</th>
</tr>
<tr>
<td>100,111</td>
<td>200</td>
<td>300</td>
</tr>
<tr>
<td>400</td>
<td>500</td>
<td>600</td>
</tr>
<tr>
<td>Text</td>
<td>More text</td>
<td>Text with
new line</td>
</tr>
</table>
</body>
다른 방법은 대부분 시도해 보았기 때문에 사용하기가 매우 쉽습니다.
서버 측에서는 PHP 스크립트가 필요하지 않습니다.Data URI를 허용하는 브라우저에서 클라이언트 측에서만 이 작업을 수행합니다.
data:application/csv;charset=utf-8,content_encoded_as_url
데이터 URI는 다음과 같습니다.
data:application/csv;charset=utf-8,Col1%2CCol2%2CCol3%0AVal1%2CVal2%2CVal3%0AVal11%2CVal22%2CVal33%0AVal111%2CVal222%2CVal333
이 URI는 다음과 같이 호출할 수 있습니다.
- 용사를
window.open - 는또설정 합니다.
window.location - 또는 닻의 href에 의하여.
- 다운로드 속성을 추가하면 크롬에서 작동할 것이며, 여전히 IE에서 테스트해야 합니다.
테스트하려면 위의 URI를 복사하여 브라우저 주소 표시줄에 붙여넣기만 하면 됩니다.또는 HTML 페이지에서 아래 앵커를 테스트합니다.
<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>
표에서 값을 가져와 내용을 작성하려면 표 2를 사용합니다.멜란시아가 언급한 CSV영국 및 수행:
var csv = $table.table2CSV({delivery:'value'});
window.location.href = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(csv);
이 문제에 대한 네이티브 Javascript 솔루션입니다.대부분의 최신 브라우저에서 작동합니다.
function export2csv() {
let data = "";
const tableData = [];
const rows = document.querySelectorAll("table tr");
for (const row of rows) {
const rowData = [];
for (const [index, column] of row.querySelectorAll("th, td").entries()) {
// To retain the commas in the "Description" column, we can enclose those fields in quotation marks.
if ((index + 1) % 3 === 0) {
rowData.push('"' + column.innerText + '"');
} else {
rowData.push(column.innerText);
}
}
tableData.push(rowData.join(","));
}
data += tableData.join("\n");
const a = document.createElement("a");
a.href = URL.createObjectURL(new Blob([data], { type: "text/csv" }));
a.setAttribute("download", "data.csv");
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
table {
border-collapse: collapse;
}
td, th {
border: 1px solid #aaa;
padding: 0.5rem;
text-align: left;
}
td {
font-size: 0.875rem;
}
.btn-group {
padding: 1rem 0;
}
button {
background-color: #fff;
border: 1px solid #000;
margin-top: 0.5rem;
border-radius: 3px;
padding: 0.5rem 1rem;
font-size: 1rem;
}
button:hover {
cursor: pointer;
background-color: #000;
color: #fff;
}
<table>
<thead>
<tr>
<th>Name</th>
<th>Author</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>jQuery</td>
<td>John Resig</td>
<td>The Write Less, Do More, JavaScript Library.</td>
</tr>
<tr>
<td>React</td>
<td>Jordan Walke</td>
<td>React makes it painless to create interactive UIs.</td>
</tr>
<tr>
<td>Vue.js</td>
<td>Yuxi You</td>
<td>The Progressive JavaScript Framework.</td>
</tr>
</tbody>
</table>
<div class="btn-group">
<button onclick="export2csv()">csv</button>
</div>
순수한 Javascript 라이브러리를 원하는 경우 FileSaver.js를 사용하여 파일 다운로드를 트리거하기 위한 코드 스니펫을 저장할 수 있습니다.또한 FileSaver.js는 내보내기 위한 콘텐츠를 구성하지 않습니다.당신이 원하는 형식으로 콘텐츠를 직접 구성해야 합니다.
현대적인 해결책
여기서 제안된 솔루션의 대부분은 td 요소 내에 내포된 테이블 또는 기타 요소와 함께 중단됩니다.테이블 내의 다른 요소를 자주 사용하지만 맨 위 테이블만 내보내려고 합니다.저는 여기서 발견된 코드의 일부를 칼루마에서 가져왔고 현대적인 바닐라 ES6 JS에 추가했습니다.
textContent를 innerText로 사용하는 것이 innerText보다 더 나은 해결책입니다. innerText는 td 요소 내부의 HTML을 반환합니다.그러나 textContent도 중첩된 요소에서 텍스트를 반환합니다.더 나은 솔루션은 td에서 사용자 지정 데이터 특성을 사용하고 여기서 CSV 값을 가져오는 것입니다.
해피 코딩!
function downloadAsCSV(tableEle, separator = ','){
let csvRows = []
//only get direct children of the table in question (thead, tbody)
Array.from(tableEle.children).forEach(function(node){
//using scope to only get direct tr of node
node.querySelectorAll(':scope > tr').forEach(function(tr){
let csvLine = []
//again scope to only get direct children
tr.querySelectorAll(':scope > td').forEach(function(td){
//clone as to not remove anything from original
let copytd = td.cloneNode(true)
let data
if(copytd.dataset.val) data = copytd.dataset.val.replace(/(\r\n|\n|\r)/gm, '')
else {
Array.from(copytd.children).forEach(function(remove){
//remove nested elements before getting text
remove.parentNode.removeChild(remove)
})
data = copytd.textContent.replace(/(\r\n|\n|\r)/gm, '')
}
data = data.replace(/(\s\s)/gm, ' ').replace(/"/g, '""')
csvLine.push('"'+data+'"')
})
csvRows.push(csvLine.join(separator))
})
})
var a = document.createElement("a")
a.style = "display: none; visibility: hidden" //safari needs visibility hidden
a.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csvRows.join('\n'))
a.download = 'testfile.csv'
document.body.appendChild(a)
a.click()
a.remove()
}
편집: cloneNode()가 cloneNode(true)로 업데이트되어 내부로 들어갑니다.
위의 답변을 사용했지만, 필요에 따라 변경했습니다.
저는 다음 기능을 사용하여 CSV 파일을 다운로드해야 하는 REACT 파일로 가져왔습니다.
는 는나가 .span 내 태 그 안 내에 th 에 주석을 추가했습니다.대부분의 함수/메소드가 수행하는 작업에 주석을 추가했습니다.
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로 이동하면 다음 기능이 반응하여 트리거됩니다.
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>
저는 이것을 위한 도서관이 있다는 것을 발견했습니다.다음 예를 참조하십시오.
https://editor.datatables.net/examples/extensions/exportButtons.html
위의 코드 외에도 다음 Javascript 라이브러리 파일이 이 예제에서 사용하기 위해 로드됩니다.
HTML에 다음 스크립트를 포함합니다.
jquery.dataTables.min.js
dataTables.editor.min.js
dataTables.select.min.js
dataTables.buttons.min.js
jszip.min.js
pdfmake.min.js
vfs_fonts.js
buttons.html5.min.js
buttons.print.min.js
다음과 같은 스크립트를 추가하여 버튼을 활성화합니다.
<script>
$(document).ready( function () {
$('#table-arrays').DataTable({
dom: '<"top"Blf>rt<"bottom"ip>',
buttons: ['copy', 'excel', 'csv', 'pdf', 'print'],
select: true,
});
} );
</script>
어떤 이유로 Excel 내보내기를 수행하면 파일이 손상되지만 복구할 수 있습니다.또는 Excel을 사용하지 않도록 설정하고 csv 내보내기를 사용합니다.
저는 위에 게시된 Calumah의 기능을 사용했지만, 그의 코드에 문제가 생겼습니다.
행이 세미콜론으로 결합됩니다.
csv.push(row.join(';'));
그러나 생성된 링크의 내용 유형은 "text/csv"입니다.
Windows에서는 문제가 없지만 Mac용 Excel에서는 문제가 발생합니다.배열 조인을 쉼표로 변경했는데 완벽하게 작동했습니다.
언급URL : https://stackoverflow.com/questions/15547198/export-html-table-to-csv-using-vanilla-javascript
'programing' 카테고리의 다른 글
| Android - 오류:':app:transformClassesWithDexForRelease' 작업을 실행하지 못했습니다. (0) | 2023.09.02 |
|---|---|
| Android SDK 위치 (0) | 2023.09.02 |
| MySQL의 저장 프로시저 내에 선택적 매개 변수를 작성하시겠습니까? (0) | 2023.09.02 |
| 목록 상자에서 텍스트 상자 항목을 선택해도 목록 상자의 선택한 항목은 변경되지 않습니다. (0) | 2023.04.20 |
| 왜 차르가 없지?문자열처럼 비어 있습니다.비어있나요? (0) | 2023.04.20 |