3

我正在 MVC 中实现导出到 csv。
由于参数是日期时间类型,由于用户文化不同,我需要在帖子中发送数据。

服务器代码:

[HttpPost]
public async Task<FileResult> ExportBomTotal(ReportRequestVM reportRequestVM)
{
    List<MyData> result = await service.getData(reportRequestVM);
    string fileName = string.Format("file{0}-{1} .csv", reportRequestVM.StartDate.ToShortDateString(), reportRequestVM.EndDate.ToShortDateString());
    return new CSVResult<MyData>(result) { FileDownloadName = fileName };
}

在客户端,我试图像这样在帖子中发送数据:

$.ajax({
    url: '@Url.Action("ExportBomTotal", "Analytics")',
    type: 'POST',
    data: JSON.stringify(searchParameters),
    contentType: 'application/json',
    success: function (data) {
        debugger;
    //  window.location.assign(data);
    // window.location.replace(data);
    },
    error: function (response) {
        debugger;
    },
    cache: false
});

日期被传递到服务器,到目前为止这很好,但我无法获得下载文件弹出窗口。
我想我需要使用 window.location 但请求必须是后期操作。

对于那些如何要求 CSVResult 公共密封类 CSVResult : FileResult where T : class { private readonly IEnumerable _collection;

    public CSVResult(IEnumerable<T> collection)
        : base("text/csv")
    {
        _collection = collection;
    }

    protected override void WriteFile(HttpResponseBase response)
    {
        Stream outputStream = response.OutputStream;
        using (MemoryStream mstream = new MemoryStream())
        {
            WriteObject(mstream);
            outputStream.Write(mstream.GetBuffer(), 0, (int)mstream.Length);
        }
    }

    private void WriteObject(Stream stream)
    {
        // We will follow the recommandations stated in this article
        // http://www.commentcamarche.net/faq/sujet-7273-exporter-a-coup-sur-du-csv
        StreamWriter writer = new StreamWriter(stream, System.Text.Encoding.Default);
        //modelType.
        Dictionary<string, bool> dict = new Dictionary<string, bool>();

        // Render columns
        Type modelType = typeof(T);
        PropertyInfo[] props = modelType.GetProperties();
        foreach (PropertyInfo prop in props)
        {
            object[] attrs = prop.GetCustomAttributes(true);
            foreach (VisibleAttribute visible in attrs.OfType<VisibleAttribute>())
            {
                dict.Add(prop.Name, visible.Hide);
            }
        }
        List<ModelMetadata> metadatas = ModelMetadataProviders.Current.GetMetadataForProperties(null, modelType)
            .Where(m => !dict.ContainsKey(m.PropertyName) || dict[m.PropertyName] )
                .OrderBy(p => p.Order).ToList();

        foreach (ModelMetadata t in metadatas)
        {
            WriteValue(writer, t.DisplayName ?? t.PropertyName);
        }

        writer.WriteLine();
        // Render data
        var en = _collection.GetEnumerator();
        while (en.MoveNext())
        {
            ModelMetadata mprop = ModelMetadataProviders.Current.GetMetadataForType(() => en.Current, modelType);

            var allowedProperties = mprop.Properties
                .Where(m => !dict.ContainsKey(m.PropertyName) || dict[m.PropertyName]);
            foreach (ModelMetadata prop in allowedProperties)
            {
                WriteValue(writer, prop.SimpleDisplayText ?? String.Empty);
            }
            writer.WriteLine();
        }
        writer.Flush();
    }
    /// <summary>
    /// Writes the value.
    /// </summary>
    /// <param name="writer">The writer.</param>
    /// <param name="literal">The literal.</param>
    private static void WriteValue(StreamWriter writer, String literal)
    {
        // Enclose values in quote
        writer.Write("\"");
        string line = literal;//.Replace("\"", "\"\"");
        writer.Write(line);
        writer.Write("\",");
    }
}

任何建议将不胜感激,
1o,
罗尼

4

2 回答 2

0

但我无法弹出下载文件

这很正常。您不能使用 AJAX 下载文件。您的 AJAX 请求的成功回调将被执行并作为数据参数传递给您可以在客户端上操作的 CSV 生成文件,但您无法使用任何另存为对话框进行提示。

如果您想实现这一点,您应该提供一个标准的 HTML 表单,其中包含您可以使用 javascript 触发其提交的所需参数。作为替代方案,如果您没有很多参数,您可以使用指向控制器操作的标准锚点。

于 2013-05-13T15:31:34.603 回答
0

这是不可能的。您不能强制浏览器下载您已经通过 ajax 调用收到的数据。

如果您确实必须发布数据,您可以使用 javascript 提交表单来触发您的下载操作。

如果获取就足够了,您可以location.href使用下载操作的链接进行分配。

编辑:表格示例

@using (Html.BeginForm("ExportBomTotal", "Analytics") {

   ... render your searchparameters as html inputs

}

// submit the form with javascript:
$('form').submit();
于 2013-05-13T15:31:49.500 回答