将ReactJS对象下载为文件

时间:2015-07-03 22:03:42

标签: javascript jquery ajax reactjs react-jsx

我正在使用连接到Express API服务器的ReactJS前端构建应用程序。使用Ajax调用API。

在我的一个视图中,表格加载了"导出"每行的链接。导出链接指向一个React路由,该路由调用API端点,该端点提供要下载的CSV文件。

如果我直接使用有效请求(在React应用程序之外)命中API端点,则会在浏览器中启动文件下载。完善!但是,在React页面的Export链接后,尝试加载发生API调用的视图。该表从视图中消失,并被文件内容替换(为了证明我有数据),但没有下载文件。

我可以强制将响应对象的内容下载为文件吗? 这可能发生在ajax成功回调中吗? 我尝试使用javascript,但我正在努力使用React虚拟DOM ... 我认为这必须非常直接,但我很难过。

编辑:@Blex的评论帮助我解决了这个问题!该解决方案已添加到代码段...

这是接收数据的JSX:

module.exports = React.createClass({

    mixins: [Router.State],
    getInitialState: function() {
        return {
            auth: getAuthState(),
            export: [],
            passedParams: this.getParams()
        };
    },

    componentDidMount: function(){
        $.ajax({
            type: 'GET',
            url: ''+ API_URL +'/path/to/endpoint'+ this.state.passedParams.id +'/export',
            dataType: 'text',
            headers: {
                'Authorization': 'Basic ' + this.state.auth.base + ''
            },
            success: function (res) {
                // can I force a download of res here?
                console.log('Export Result Success -- ', res);
                if(this.isMounted()){
                    console.log('Export Download Data -- ', res);
                    this.setState({export: res[1]});
                    // adding the next three lines solved my problem
                    var data = new Blob([res], {type: 'text/csv'});
                    var csvURL = window.URL.createObjectURL(data);
                    //window.open(csvURL);
                    // then commenting out the window.open & replacing
                    // with this allowed a file name to be passed out
                    tempLink = document.createElement('a');
                    tempLink.href = csvURL;
                    tempLink.setAttribute('download', 'filename.csv');
                    tempLink.click();
                }
            }.bind(this),
            error: function (data) {
                console.log('Export Download Result Error -- ', data);
            }
        });
    },

    render: function(){
        console.log('exam assignment obj -- ', this.state.passedParams.name);
        var theFileContents = this.state.export;
            return(
            <div className="row test-table">
                <table className="table" >
                    <tr className="test-table-headers">
                    {theFileContents} // this loads the contents
                    // can I auto download theFileContents?
                    </tr>
                </table>
            </div>
            )
    }
});

2 个答案:

答案 0 :(得分:13)

根据@blex的评论添加以下代码,文件下载工作正常。要在上下文中查看它,请查看问题中的成功回调。

var data = new Blob([res], {type: 'text/csv'});
var csvURL = window.URL.createObjectURL(data);
tempLink = document.createElement('a');
tempLink.href = csvURL;
tempLink.setAttribute('download', 'filename.csv');
tempLink.click();

答案 1 :(得分:0)

我在React应用程序中使用了一个软件包jsonexport,现在可以单击链接下载csv文件。 这是我所做的:

.
.
import React, {useState,useEffect} from 'react';// I am using React Hooks
import * as jsonexport from "jsonexport/dist";
.
.
.
const [filedownloadlink, setFiledownloadlink] = useState("");//To store the file download link

.
.
.

创建一个将为CSV提供数据的函数。它也可以在网络请求的回调中。调用此方法时,它将以filedownloadlink状态设置值。

function handleSomeEvent(){
var contacts = [{
        name: 'Bob',
        lastname: 'Smith'
    },{
        name: 'James',
        lastname: 'David'
    },{
        name: 'Robert',
        lastname: 'Miller' 
    },{
        name: 'David',
        lastname: 'Martin'
    }];

    jsonexport(contacts,function(err, csv){
        if(err) return console.log(err);
        var myURL = window.URL || window.webkitURL //window.webkitURL works in Chrome and window.URL works in Firefox
        var csv = csv;  
        var blob = new Blob([csv], { type: 'text/csv' });  
        var csvUrl = myURL.createObjectURL(blob);
        setFiledownloadlink(csvUrl);
    });
}

在render函数中使用类似以下的内容:

{filedownloadlink &&<a download="UserExport.csv" href={filedownloadlink}>Download</a>}

filedownloadlink有一些数据要下载时,以上链接将可见。