在 jQuery 中导出为 csv

Posted

技术标签:

【中文标题】在 jQuery 中导出为 csv【英文标题】:Export to csv in jQuery 【发布时间】:2011-06-06 01:53:25 【问题描述】:

我正在动态生成一个类似于:

<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 吗?

也需要一个文件保存对话框,像这样:

谢谢。

【问题讨论】:

正在寻找客户端解决方案并需要避免服务器调用 excel实际上可以导入像你一样格式化的html 几个 javascript 库将执行此操作,包括 DataTable 是否可以选择“将表格作为 CSV 复制到剪贴板”?如果是,那么您可以使用一些 javascript/jQuery 从您的表中收集数据并对其进行格式化(在您的情况下为 CSV),然后使用 ZeroClipboard js libary 将此格式化数据复制到剪贴板(此插件由 github 和其他使用知名网站)。 “以 CSV 格式将表格复制到剪贴板”jsfiddle.net/h2Kq6/ 的示例 【参考方案1】:

您只能在客户端执行此操作,在接受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 或通过锚点的href 通过添加 download 属性,它可以在 chrome 中运行,但仍然需要在 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>

要创建内容,从表中获取值,您可以使用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 版本上获得类似的行为。

【讨论】:

这适用于/不适用于哪些浏览器?它似乎在 Chrome 中不起作用。 Chrome 支持数据 URI。看看:en.wikipedia.org/wiki/Data_URI#Web_browser_support 所以它说,但我测试了你的答案,它对我来说在 IE9 或 Chrome 上都不起作用。 @italo 当我通过window.locationwindow.open 执行此操作时,它会将其保存为“x4ef3.part”,而不是“somename.csv”。如何使其另存为“.csv”文件? 在 Firefox 23 和 Chrome 28 上对此进行了测试,并且可以正常工作。无法在 IE11 上测试。【参考方案2】:

这是我的实现(基于: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);

注意事项

它使用“th”标签作为标题。如果它们不存在,则它们不存在 添加。 此代码检测以下格式的数字:-####.##(您需要修改代码以接受其他格式,例如使用逗号)。

更新

我之前的实现运行良好,但没有设置 csv 文件名。代码被修改为使用文件名,但它需要一个 元素。似乎您无法动态生成 元素并触发“click”事件(也许是出于安全原因?)。

演示

http://jsfiddle.net/nLj74t0f/

(不幸的是,jsfiddle 无法生成文件,而是抛出错误:'please use POST request',不要让该错误阻止您在应用程序中测试此代码)。

【讨论】:

我认为 if $(this).find("td").each(function() 在检查 th 之后的 else 中还有一个额外的语句。 谢谢,上面也用过***.com/a/7588465/805366jsfiddle.net/santeriv/qtQPf【参考方案3】:

我最近为此发布了一个免费软件库:"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() 在内部生成一个数据 URL 链接并使用链接点击器点击它。这会将文件推送给最终用户。

根据caniuse IE10 不支持&lt;a download=...&gt;。所以对于 IE,我的库在内部调用 navigator.msSaveBlob(),如 suggested by @Manu Sharma

【讨论】:

@IanLim 我在上面的 SO 链接中加入了该技术,可以确认 html5csv 库现在在 IE11 中生成 csv 文件。【参考方案4】:

这里有两个解决方法来解决仅从客户端触发下载的问题。在以后的浏览器中,您应该查看“blob”


1.拖放表格

您知道您可以简单地将表格拖放到 Excel 中吗?

这里是如何选择要剪切和过去或拖动的表格

Select a complete table with Javascript (to be copied to clipboard)


2。从您的 div 中创建一个弹出页面

虽然它不会产生保存对话框,但如果 resulting 弹出窗口以扩展名 .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();

免责声明:这些是解决方法,并不能完全回答目前大多数浏览器都有答案的问题:仅在客户端上不可能

【讨论】:

再一次没有评论的反对票。除非您发表评论,否则毫无价值! 获得 CSV 数据后,您可以使用download="myfile.csv"type="text/csv" 属性创建a,使用btoa 将CSV 数据编码为base64,并将src 属性设置为"data:text/csv;base64,P2ZyB4bW.....xucz0===",将a 元素附加到DOM(隐藏它)并单击它,它将下载文件。 是的,我知道,已在此页面的另一个答案中回答。【参考方案5】:

仅使用 jQuery,您无法避免服务器调用。

但是,为了实现这个结果,我使用了Downloadify,它可以让我保存文件而无需进行另一个服务器调用。这样做可以减少服务器负载并提供良好的用户体验。

要获得正确的 CSV,您只需删除所有不必要的标签并在数据之间添加一个“,”。

【讨论】:

这个东西需要 Flash,所以它不能移植到所有的浏览器上,用数据检查下面的答案:应用程序驱动的 HREF。简单、干净。 本方案除了需要Flash外,不符合题主要求:使用jQuery,避免服务器调用。 好吧,Pratik 说客户端并避免服务器调用。便携性并不总是很重要。如果它符合他的需要,为什么不呢。 Flash 对客户造成负担,并且由于减少了对跨设备 Flash 的支持,因此严重不推荐。【参考方案6】:

您无法避免这里的服务器调用,JavaScript 根本无法(出于安全原因)将文件保存到用户的文件系统。您必须将数据提交到服务器并让直接将.csv 作为链接或附件发送。

HTML5 has some ability to do this(虽然没有指定保存 - 只是一个用例,如果需要,您可以读取文件),但现在没有跨浏览器解决方案。

【讨论】:

您可以避免服务器调用。因此对 italo 的回答表示赞成。【参考方案7】:

希望下面的演示可以帮助到你。

$(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>

【讨论】:

【参考方案8】:

只需尝试以下编码...使用 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>

【讨论】:

以上是关于在 jQuery 中导出为 csv的主要内容,如果未能解决你的问题,请参考以下文章

在 PowerShell 中导出为 CSV 时如何指定列顺序?

在 React-Table 中导出为 PDF

在 Adob​​e Illustrator 画布大小问题中导出为 SVG [关闭]

捕获视频帧,然后在 HTML5 中导出为位图

SSIS 2008 - 在平面文件目标中导出为指数值的浮点值

将 HTML 表单弹出为 JQuery 对话框时,如何避免自动关注第一个输入字段?