csv - 将 d3 生成的 HTML 表导出为 CSV(也必须在 IE 上工作)

标签 csv d3.js html-table export-to-csv

在 JavaScript 中,我进行了 ajax/xhr d3.csv() 调用,这会触发一个冗长的 MySQL 查询(有时可能需要超过 30 秒才能运行)。然后根据数据生成 HTML 表格 ( via d3.js )。

我希望用户能够通过单击按钮将数据下载为 CSV 文件,但是

  • 我不想为此在服务器上创建 tmp 文件
  • 无法在服务器上再次运行查询 - 我不想让用户再等待 30 秒(也不想再次绑定(bind)数据库)
  • 我想指定文件名,例如 descriptiveName-some_datetime_here.csv
  • 它需要在 IE(美国公司的事物)和 Safari(公司高管的事物)中工作

将 d3 创建的 JSON 数据转换为 CSV 不是问题(我知道如何执行该部分)。

有很多类似的 SO 问题,普遍的共识似乎是:
使用数据 URI 并在 download 属性中指定文件名( Q1Q2 、等)。
但遗憾的是这个属性是 not supported on IE or Safari .

最佳答案

也许有更好的方法,但这里有一种方法:提交一个具有所需文件名的表单,并将数据作为两个隐藏的表单元素。让服务器简单地返回带有为文件下载设置的适当 header 的数据。不需要tmp文件;适用于所有浏览器。

HTML:

<form id="download-form" method="post">
   <input type="button" value="download CSV">
</form>
<!-- the button is right above the HTML table -->
<table>... </table>

JavaScript/D3:

var jsonData;
var filenameDateFormat = d3.time.format("%Y%m%d-%H%M%S");
// ... after loading the data, and setting jsonData to the data returned from d3.csv()
jsonData = data;
// display the form/button, which is initially hidden
d3.select("#download-form").style("display", "block");

d3.select("#download-form input[type=button]").on('click', function() {
    var downloadForm = d3.select("#download-form");
    // remove any existing hidden fields, because maybe the data changed
    downloadForm.selectAll("input[type=hidden]").remove();
    downloadForm
        .each(function() {
            d3.select(this).append("input")
                .attr({ type:  "hidden",
                        name:  "filename",
                        value: CHART_NAME + "-" 
                               + filenameDateFormat(new Date()) + ".csv"});
            d3.select(this).append("input")
                .attr({ type:  "hidden",
                        name:  "data",
                        value: convertToCsv(jsonData) });
        });
    document.getElementById("download-form").submit();
});
function convertToCsv(data) {
    var csvArray = ['field_name1_here,field_name2_here,...'];
    data.forEach(function(d) {
        csvArray.push(d.field_name1_here + ',' + d.field_name2_here + ...);
    });
    return csvArray.join("\n");
}

服务器(Python,使用 Bottle ):

@app.route('/download', method='POST')
def download():
    if request.environ.get('HTTP_USER_AGENT').find('Chrome'):
        # don't add the Content-Type, as this causes Chrome to output the following
        # to the console:
        #  Resource interpreted as Document but transferred with MIME type text/csv
        pass
    else:
        response.set_header('Content-Type', 'text/csv')
    response.set_header('Content-Disposition',
        'attachment; filename="' + request.forms.filename + '"')
    return request.forms.data

虽然不太漂亮,但确实有效。

关于csv - 将 d3 生成的 HTML 表导出为 CSV(也必须在 IE 上工作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20158236/

相关文章:

将文本文件转换为 CSV 文件的 C 程序

reactjs - 如何从 fetch 请求中的 readableStream 响应中获取可下载文件

html - Angularjs:如何根据用户输入更新表的值?

html - td 标签内容未右对齐

python - 如何按顺序循环/解析表行而不跳到变量的下一个实例?

javascript - 在 Javascript 中将 CSV 转换为嵌套的 JSON

java - 打开csv集合和连续数组

html - 在 Hugo 帖子中插入 js

javascript - d3.js 使用不同的数据创建相同的 svg 对象

javascript - 删除了不正确的 SVG 组