【问题标题】:.NET Core Web API Return CSV in Reactjs.NET Core Web API 在 Reactjs 中返回 CSV
【发布时间】:2021-08-19 14:11:37
【问题描述】:

我使用如下所示的 csvformatter 代码从 API 返回一个 csv 文件 API 调用

[HttpGet("generatecsv/project/{projectId}/BookID/{bookId}")]
[Produces("text/csv")]
    public IActionResult Getcsv(string projectId, string bookId)
    {
        try
        {
            Models model = GetModel();
            return Ok(model);
        }
        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }
    }

CSV 格式化程序

public class CSVOutputFormatter : OutputFormatter
    {
        public string ContentType { get; }
        public PDRDModels ViewModel { get; set; }

        public CSVOutputFormatter()
        {
            ContentType = "text/csv";
            SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(ContentType));
        }

        public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
        {
            var response = context.HttpContext.Response;
            var filePath = string.Format("./DataExport/PDRD-{0}.csv", DateTime.Now.Ticks);
            ViewModel = context.Object as Models;

            using (var writer = new StreamWriter(filePath))
            using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
            {
                csv.WriteField("StackUp Information");
                csv.NextRecord();
                csv.NextRecord();
                WriteToCSV1(csv, ViewModel.Data1);
                foreach (var pdrdModel in ViewModel.PDRDModelList)
                {
                    csv.NextRecord();
                    csv.WriteField($"Physical Rules");
                    csv.NextRecord();
                    WriteToCSV2(ViewModel.Data2);
                }
            }
            response.Headers.Add("Content-Disposition", "attachment;filename=Pdrd.csv");
            response.ContentType = "text/csv";

            await response.SendFileAsync(filePath);
        }
    }
}

API 在通过浏览器或 Postman 访问时将 csv 文件作为附件返回。但是当通过 UI 代码时,它只是将 csv 响应作为字符串而不是附件返回。 下面是到达上述终点的 UI 代码。

export const getExportedValues = async (projectId: string, bookId: string) => {
    if (projectId && bookId) {
        const finalUrl: string = `${getEnvConfig().projectsAPIUrl}/document/generatecsv/project/${projectId}/bookID/${bookId}`;
        let resp: any = await axios({ method: AxiosMethods.GET, url: finalUrl }).catch(err => errorFunction(err))
        if (!resp?.data?.error) {
            return resp?.data;
        }
    } else return {}

}

我在我的 reactjs 代码中缺少什么让这个下载为纯 csv 文本的附件

【问题讨论】:

  • 尝试在您的Getcsv 方法中返回FileContentResult。在您的网络应用程序中单击此链接后,它将自动下载。 You can refer my sample code
  • 我对csv的内容类型不熟悉,你的代码一定比我的示例代码好。如果我的回复有帮助,请接受它作为答案(单击回复旁边的标记选项将其从灰色切换为填写。),请参阅meta.stackexchange.com/questions/5234/…

标签: csv asp.net-core


【解决方案1】:

您在 axios 中的代码应该如下所示。创建<a></a> 标签并点击它,类似于我评论中的链接。

function invoke() {
    axios({
        url: '/ForTest/ExportData',
        method: 'GET',
        responseType: 'blob', // important
    }).then((response) => {
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', 'file.csv'); //or any other extension
        document.body.appendChild(link);
        link.click();
    });

我的测试代码

@{
    ViewData["Title"] = "Home Page";
}

@*<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>. 
    </p>
</div>*@
<div class="text-center">
    <a href="/ForTest/ExportData">download link</a>
</div>

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
    function invoke() {
        axios({
            url: '/ForTest/ExportData',
            method: 'GET',
            responseType: 'blob', // important
        }).then((response) => {
            const url = window.URL.createObjectURL(new Blob([response.data]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', 'file.csv'); //or any other extension
            document.body.appendChild(link);
            link.click();
        });
    }
</script>

<div class="text-center">
    <a onclick="invoke()">download_by_axios</a>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-11
    • 2019-04-22
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 2023-01-12
    相关资源
    最近更新 更多