简体   繁体   English

如何下载服务器在 Ajax 调用中返回的文件?

[英]How do I download a file that is returned by the server in an Ajax call?

I have a download function where the idea is that when the user clicks a button, it does an ajax call to a function that will create a csv file containing all of the information the user was viewing, and will return the file as a download.我有一个下载函数,其中的想法是当用户单击按钮时,它会调用一个函数,该函数将创建一个包含用户正在查看的所有信息的 csv 文件,并将该文件作为下载返回。 I have the server function creating a csv file, but I'm not sure how to make it download.我有创建 csv 文件的服务器功能,但我不确定如何下载它。 This is my server-side code:这是我的服务器端代码:

public ActionResult Download(Guid customerOrderId)
{
    var order = this.UnitOfWork.GetRepository<CustomerOrder>().Get(customerOrderId);

    var csv = new StringBuilder();

    csv.Append("Customer,Bill To Name,Ship To Name,Patient,Order#,Order Date," +
        "Line,Item#,Item Description,Qty,UOM,Price,Ext Price,Carrier," +
        "Notes,Purchase Order");

    var customer = order.CustomerNumber;
    var billToName = order.BTDisplayName;
    var shipToName = order.ShipTo.CustomerName;
    var orderNum = order.OrderNumber;
    var orderDate = order.OrderDate;
    var carrier = order.ShippingDisplay;
    var notes = order.Notes;
    var subtotal = order.OrderSubTotalDisplay;
    var total = order.OrderGrandTotalDisplay;
    var shipping = order.ShippingAndHandling;
    var tax = order.TotalSalesTaxDisplay;
    var patient = "";
    var purchaseOrder = order.CustomerPO;
    foreach (var cartLine in order.OrderLines)
    {
        var line = cartLine.Line;
        var itemNum = cartLine.Product.ProductCode;
        var itemDesc = cartLine.Description;
        var qty = cartLine.QtyOrdered;
        var uom = cartLine.UnitOfMeasure;
        var price = cartLine.ActualPriceDisplay;
        var ext = cartLine.ExtendedActualPriceDisplay;

        //Customer,Bill To Name,Ship To Name,Patient,Order#,Order Date," + 
        //"Line,Item#,Item Description,Qty,UOM,Price,Ext Price,Carrier," +
        //"Notes,Purchase Order
        var newLine = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}",
            customer, billToName, shipToName, patient, orderNum, orderDate, line, itemNum, itemDesc,
            qty, uom, price, ext, carrier, notes, purchaseOrder);

        csv.AppendLine(newLine);
    }

    csv.AppendLine();
    csv.AppendLine("Subtotal,Shipping & Handling,Tax,Total");
    csv.AppendLine(string.Format("{0},{1},{2},{3}", subtotal, shipping, tax, total));

    var filename = "MSD-Order-" + orderNum + ".csv";            

    var bytes = Encoding.UTF8.GetBytes(csv.ToString());
    return this.File(bytes, "text/csv");
}

And here is the ajax method:这是 ajax 方法:

function download(customerOrderId) {
    $.ajax({
        url: insite.core.actionPrefix + '/Checkout/Download/?customerOrderId=' + customerOrderId,
        type: 'Post',
        contentType: "application/json; charset=utf-8",
        async: false,
        cache: false,
        success: function (data) {
            alert("downloaded");
        },
        error: function (ex) {
            console.log(ex);
        }
    });    
}

In the success of the ajax call, I checked the value of "data" and it has the information, but I'm not sure how to make it download.在ajax调用成功时,我检查了“data”的值,它有信息,但我不知道如何下载。 What do I do once I receive the data?收到数据后怎么办?

Can't you just download it via a href like this?你不能通过这样的href下载它吗?

public FileContentResult Download(Guid customerOrderId)
{
    // your code

    var response = new FileContentResult(bytes, "text/csv");
    response.FileDownloadName = filename;
    return response;
}

The link:链接:

<a href="Checkout/Download/?customerOrderId=someId">Download</a>

You can store the file on server and send the URL with response.您可以将文件存储在服务器上并发送带有响应的 URL。 Then on ajax success function window.location=data.URL然后在ajax上成功函数window.location=data.URL

Venerik has a valid answer as well, but keeping in line with your current implementation, I'd suggest the following. Venerik 也有一个有效的答案,但与您当前的实施保持一致,我建议如下。

You can return the string of the URL after saving the file to your server.将文件保存到服务器后,您可以返回 URL 的字符串。 Then do the window location redirection upon your success.然后在成功后进行窗口位置重定向。 I removed the variable assignments since nothing is being done with them other than sending to a method.我删除了变量赋值,因为除了发送到方法之外没有对它们做任何事情。

Here we write the file and return the string.这里我们写入文件并返回字符串。 You'll need to adjust the return to match your site information, etc.您需要调整return以匹配您的网站信息等。

public ActionResult Download(Guid customerOrderId)
{
    var order = this.UnitOfWork.GetRepository<CustomerOrder>().Get(customerOrderId);

    var csv = new StringBuilder();

    csv.AppendLine("Customer,Bill To Name,Ship To Name,Patient,Order#,Order Date," +
        "Line,Item#,Item Description,Qty,UOM,Price,Ext Price,Carrier," +
        "Notes,Purchase Order");

    foreach (var cartLine in order.OrderLines)
    {
        //Customer,Bill To Name,Ship To Name,Patient,Order#,Order Date," + 
        //"Line,Item#,Item Description,Qty,UOM,Price,Ext Price,Carrier," +
        //"Notes,Purchase Order

        csv.AppendLine(string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}",
            order.CustomerNumber, order.BTDisplayName, order.ShipTo.CustomerName, "", order.OrderNumber, order.OrderDate, cartLine.Line, cartLine.Product.ProductCode, cartLine.Description,
            cartLine.QtyOrdered, cartLine.UnitOfMeasure, cartLine.ActualPriceDisplay, cartLine.ExtendedActualPriceDisplay, order.ShippingDisplay, order.Notes, order.CustomerPO));
    }

    csv.AppendLine();
    csv.AppendLine("Subtotal,Shipping & Handling,Tax,Total");
    csv.AppendLine(string.Format("{0},{1},{2},{3}", order.OrderSubTotalDisplay, order.ShippingAndHandling, order.TotalSalesTaxDisplay, order.OrderGrandTotalDisplay));

    var filename = "MSD-Order-" + orderNum + ".csv";  

    using (StreamWriter sw = File.CreateText(Server.MapPath("~/files/" + filename)) 
    {
        sw.Write(csv.ToString());
    } 

    // adjust your url accordingly to match the directory to which you saved
    // '/files/' corresponds to where you did the File.CreateText
    // returning Content in an ActionResult defaults to text
    return Content("http://foo.com/files/" + filename);
}

And in your AJAX method update your success function to redirect the page which will prompt the download:并在您的 AJAX 方法中更新您的成功函数以重定向将提示下载的页面:

function download(customerOrderId) {
    $.ajax({
        url: insite.core.actionPrefix + '/Checkout/Download/?customerOrderId=' + customerOrderId,
        type: 'Post',
        contentType: "application/json; charset=utf-8",
        async: false,
        cache: false,
        success: function (data) {
            window.location.href = data;
        },
        error: function (ex) {
            console.log(ex);
        }
    });    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM