Safari 添加 .html 以使用 epplus jquery.fileDownload.js 下载 xlsx

Posted

技术标签:

【中文标题】Safari 添加 .html 以使用 epplus jquery.fileDownload.js 下载 xlsx【英文标题】:Safari adding .html to download xlsx using epplus jquery.fileDownload.js 【发布时间】:2017-03-23 20:33:15 【问题描述】:

我正在使用 MVC c# 代码生成一个 excel 文件然后下载,我正在使用 EPPLUS,除了 Mac 上的 Safari 之外,一切正常,当我尝试在下载时创建文件时添加了 .html 最后,例如,file.xlsx.html 我不知道我该如何解决。

    $.fileDownload(url, 
        httpMethod: 'POST',
        data: dtColumns,
        successCallback: function() 
            //code
        ,
        failCallback: function() 
            //code

        
    );

public Stream ExportDataset(IEnumerable dataset, IList columnsToExport,string template) // 分组适用于匿名类型,因此我们可以将导出分组到他们自己的表中 var groupings = dataset.GroupBy(i => i.GetType());

        using (var package = new ExcelPackage(new FileInfo(GetTemplateFilePath(template)), true))
        
            var ws = package.Workbook.Worksheets[1];

            if (groupings.Any())
            
                // add each "anon type matched grouping"
                foreach (var grouping in groupings)
                
                    // because of EPP inheritance bug of T, we can just use dataTable
                    var dataTable = new DataTable(grouping.Key.Name);
                    var properties = grouping.Key.GetProperties(); // Get anon type Properties
                    var columns = columnsToExport.OrderBy(x => x.Position);

                    foreach (var property in columns.Where(column => column.IsVisible).SelectMany(column => properties.Where(property => property.Name.Equals(column.Name))))
                    
                        dataTable.Columns.Add(property.Name);
                    

                    foreach (var item in grouping.ToList())
                    
                        var dataRow = dataTable.NewRow();

                        foreach (var p in columns.Where(column => column.IsVisible).SelectMany(column => properties.Where(property => property.Name.Equals(column.Name))))
                        
                            dataRow[p.Name] = p.GetValue(item);
                        

                        dataTable.Rows.Add(dataRow);
                    

                    ws.Cells[1, 1].LoadFromDataTable(dataTable, PrintHeaders: true);
                    ws.Cells.AutoFitColumns();
                
            
            else
            
                // This case is when there is no data on the table to load the Excel so we create an empty sheet but we add the headers
                var datasetStructure = dataset.GetType().GetGenericArguments()[0];

                // because of EPP inheritance bug of T, we can just use dataTable
                var dataTable = new DataTable(datasetStructure.Name);
                var properties = datasetStructure.GetProperties(); // Get anon type Properties

                foreach (var property in properties)
                
                    dataTable.Columns.Add(property.Name);
                

                ws.Cells[1, 1].LoadFromDataTable(dataTable, PrintHeaders: true);
                ws.Cells.AutoFitColumns();
            

            var fileStream = new MemoryStream();
            package.SaveAs(fileStream);

            return fileStream;
        
    

在控制器上:

return new CustomFileResult(fileStream, fileName);

公共类 CustomFileResult : IHttpActionResult 私有只读流_fileContent; 私有只读字符串_fileName;

    public CustomFileResult(Stream fileContent, string fileName)
    
       _fileContent = fileContent;
       _fileName = fileName;
    

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    
        return Task.Run(() =>
        
            var response = new HttpResponseMessage();
            var fileDownloadFail = false;

            if (_fileContent == null || _fileContent.Length == 0)
            
                response.StatusCode = HttpStatusCode.InternalServerError;
                fileDownloadFail = true;

            
            else
            
                response.StatusCode = HttpStatusCode.OK;
                _fileContent.Position = 0;
                response.Content = new StreamContent(_fileContent);

                response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                
                    FileName = _fileName,
                ;
            

            //Required for plugin jquery.fileDownload.js

            var cookie = new CookieHeaderValue("fileDownload", "true")  Path = "/" ;

            response.Headers.AddCookies(new CookieHeaderValue[]  cookie ); 

            return response;

        , cancellationToken);
    

【问题讨论】:

解决方案是在响应中添加内容类型: 【参考方案1】:

解决方案是在响应中为 excel (application/vnd.ms-excel) 添加标题 ContentType。默认是text/HTML,因此Safari不理解响应包含excel文件,所以添加这一行:

response.Content.Headers.ContentType  = new MediaTypeHeaderValue("application/vnd.ms-excel");

问题解决了。

【讨论】:

以上是关于Safari 添加 .html 以使用 epplus jquery.fileDownload.js 下载 xlsx的主要内容,如果未能解决你的问题,请参考以下文章

动态添加 HTML5 日期元素 iOS Safari

HTML5 录制中等质量的视频以供 Safari 播放

iPad (iOS6) 上的 Safari 无法缩放 HTML5 视频以填充 100% 的页面宽度

在没有边框的Safari上打印

视频在 ipad 和 iphone (safari) 中没有以适当的宽度显示

Safari 音频 HTML5 问题