我正在动态生成一个div,如:
<div id='PrintDiv'>
<table id="mainTable">
<tr>
<td>
Col1
</td>
<td>
Col2
</td>
<td>
Col3
</td>
</tr>
<tr>
<td>
Val1
</td>
<td>
Val2
</td>
<td>
Val3
</td>
</tr>
<tr>
<td>
Val11
</td>
<td>
Val22
</td>
<td>
Val33
</td>
</tr>
<tr>
<td>
Val111
</td>
<td>
Val222
</td>
<td>
Val333
</td>
</tr>
</table>
</div>
页面上还有更多元素。 现在,我怎样才能获得这样的csv文件:
Col1,Col2,Col3
Val1,Val2,Val3
Val11,Val22,Val33
Val111,Val222,Val333
使用jQuery?
也需要一个文件保存dailog框,如下所示:
感谢。
答案 0 :(得分:96)
您只能在客户端,在接受Data URIs的浏览器中执行此操作:
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
要进行测试,只需复制上面的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>
要创建内容,从表中获取值,您可以使用table2CSV并执行:
var data = $table.table2CSV({delivery:'value'});
$('<a></a>')
.attr('id','downloadFile')
.attr('href','data:text/csv;charset=utf8,' + encodeURIComponent(data))
.attr('download','filename.csv')
.appendTo('body');
$('#downloadFile').ready(function() {
$('#downloadFile').get(0).click();
});
IE的大多数(如果不是全部)版本不支持导航到数据链接,因此必须实施hack,通常使用iframe
。使用iFrame
combined with document.execCommand('SaveAs'..)
,您可以在大多数当前使用的IE版本上获得类似的行为。
答案 1 :(得分:25)
这是我的实现(基于:https://gist.github.com/3782074):
<强>用法强>: HTML:
<table class="download">...</table>
<a href="" download="name.csv">DOWNLOAD CSV</a>
JS:
$("a[download]").click(function(){
$("table.download").toCSV(this);
});
<强>代码强>:
jQuery.fn.toCSV = function(link) {
var $link = $(link);
var data = $(this).first(); //Only one table
var csvData = [];
var tmpArr = [];
var tmpStr = '';
data.find("tr").each(function() {
if($(this).find("th").length) {
$(this).find("th").each(function() {
tmpStr = $(this).text().replace(/"/g, '""');
tmpArr.push('"' + tmpStr + '"');
});
csvData.push(tmpArr);
} else {
tmpArr = [];
$(this).find("td").each(function() {
if($(this).text().match(/^-{0,1}\d*\.{0,1}\d+$/)) {
tmpArr.push(parseFloat($(this).text()));
} else {
tmpStr = $(this).text().replace(/"/g, '""');
tmpArr.push('"' + tmpStr + '"');
}
});
csvData.push(tmpArr.join(','));
}
});
var output = csvData.join('\n');
var uri = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(output);
$link.attr("href", uri);
}
备注:
<强>更新强>:
我以前的实现工作正常,但没有设置csv文件名。代码被修改为使用文件名,但它需要&lt; a&gt;元件。似乎你无法动态生成&lt; a&gt;元素并触发“点击”事件(可能是安全原因?)。
<强>样本强>
(不幸的是,jsfiddle无法生成文件,而是抛出错误:'请使用POST请求',不要让错误阻止您在应用程序中测试此代码。)
答案 2 :(得分:6)
我最近发布了一个免费软件库:"html5csv.js" -- GitHub
旨在帮助简化小型模拟器应用程序的创建 在Javascript中可能需要导入或导出csv文件,操作,显示,编辑 数据,执行各种数学程序,如拟合等。
加载“html5csv.js”后,扫描表格和创建CSV的问题是单行的:
CSV.begin('#PrintDiv').download('MyData.csv').go();
这是JSFiddle demo of your example with this code。
在内部,对于Firefox / Chrome,这是一个面向数据URL的解决方案,类似于@italo,@ lepe和@adeneo提出的解决方案(在另一个问题上)。对于IE
CSV.begin()
调用设置系统将数据读入内部数组。然后发生取出。然后.download()
在内部生成数据网址链接,并使用链接点击工具点击它。这会将文件推送给最终用户。
根据caniuse,IE10不支持<a download=...>
。因此,对于IE,我的库在内部调用navigator.msSaveBlob()
,如suggested by @Manu Sharma
答案 3 :(得分:5)
以下是仅从客户端触发下载问题的两个 WORKAROUNDS 。在以后的浏览器中,您应该查看“blob”
<强> 1。拖放表格
你知道吗,你可以简单地将你的桌子拖到excel吗?
以下是如何选择要剪切和过去的表格或拖动
Select a complete table with Javascript (to be copied to clipboard)
<强> 2。从您的div创建一个弹出页面
虽然不会生成保存对话框,但如果结果弹出窗口以 .csv 扩展名保存,则会通过以下方式正确处理Excel中。
字符串可以是
w.document.write("row1.1\trow1.2\trow1.3\nrow2.1\trow2.2\trow2.3");
例如制表符分隔行的换行符。
有些插件会为您创建字符串 - 例如http://plugins.jquery.com/project/table2csv
var w = window.open('','csvWindow'); // popup, may be blocked though
// the following line does not actually do anything interesting with the
// parameter given in current browsers, but really should have.
// Maybe in some browser it will. It does not hurt anyway to give the mime type
w.document.open("text/csv");
w.document.write(csvstring); // the csv string from for example a jquery plugin
w.document.close();
免责声明:这些是解决方法,并没有完全回答目前大多数浏览器都有答案的问题:仅在客户端无法解决
答案 4 :(得分:4)
通过仅使用jQuery,您无法避免服务器调用。
但是,要实现此结果,我正在使用Downloadify,这使我可以保存文件而无需再拨打另一个服务器。这样做可以减少服务器负载并提供良好的用户体验。
要获得正确的CSV,您只需要取出所有不必要的标签,并在数据之间添加“,”。
答案 5 :(得分:1)
这里无法避免服务器调用,JavaScript根本无法(出于安全原因)将文件保存到用户的文件系统。您必须将数据提交到服务器并 it 直接将.csv
作为链接或附件发送。
HTML5 has some ability to do this(虽然没有指定保存 - 只是一个用例,如果需要,你可以读取文件),但现在没有跨浏览器解决方案。
答案 6 :(得分:0)
只需尝试以下编码...使用HTML表格的值生成CSV非常简单。没有浏览器问题
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://www.csvscript.com/dev/html5csv.js"></script>
<script>
$(document).ready(function() {
$('table').each(function() {
var $table = $(this);
var $button = $("<button type='button'>");
$button.text("Export to CSV");
$button.insertAfter($table);
$button.click(function() {
CSV.begin('table').download('Export.csv').go();
});
});
})
</script>
</head>
<body>
<div id='PrintDiv'>
<table style="width:100%">
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</div>
</body>
</html>
答案 7 :(得分:0)
希望以下演示可以帮助您。
$(function() {
$("button").on('click', function() {
var data = "";
var tableData = [];
var rows = $("table tr");
rows.each(function(index, row) {
var rowData = [];
$(row).find("th, td").each(function(index, column) {
rowData.push(column.innerText);
});
tableData.push(rowData.join(","));
});
data += tableData.join("\n");
$(document.body).append('<a id="download-link" download="data.csv" href=' + URL.createObjectURL(new Blob([data], {
type: "text/csv"
})) + '/>');
$('#download-link')[0].click();
$('#download-link').remove();
});
});
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;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='PrintDiv'>
<table id="mainTable">
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
</tr>
<tr>
<td>Val1</td>
<td>Val2</td>
<td>Val3</td>
</tr>
<tr>
<td>Val11</td>
<td>Val22</td>
<td>Val33</td>
</tr>
<tr>
<td>Val111</td>
<td>Val222</td>
<td>Val333</td>
</tr>
</table>
</div>
<div class="btn-group">
<button>csv</button>
</div>