FileContentResult 返回 excel 文件损坏

问题描述 投票:0回答:3

我正在尝试从 ftp 下载 xlsx 文件,但当我下载并尝试打开它时,我发现它是一个损坏的文件。 。我分享背面和正面的代码。

public async Task<TransacResult> DownloadFileInterface(Uri serverUri, string fileName)
    {
        StreamReader sr;
        byte[] fileContent;
        try
        {
            string ftpUser = GetConfiguration()["SuatKeys:FTPSuatUser"];
            string ftpPassword = GetConfiguration()["SuatKeys:FTPSuatPassword"];

            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
            request.Method = WebRequestMethods.Ftp.DownloadFile;
            request.KeepAlive = false;
            request.Credentials = new NetworkCredential(ftpUser, ftpPassword);
            sr = new StreamReader(request.GetResponse().GetResponseStream());
            fileContent = Encoding.UTF8.GetBytes(sr.ReadToEnd());
            sr.Close();
            sr.Dispose();
            FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync();
            var fileContentResult = new FileContentResult(fileContent, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
            {
                FileDownloadName = fileName + ".xlsx"
            };
            return new TransacResult(true, fileContentResult);
        }
        catch (Exception ex)
        {
            return new TransacResult(false, new Message("SUAT-ERR-C02", MessageCategory.Error, "Conexión rechazada", ex.Message));
        }
    }

async downloadlayout() {
    var obj = this.interfaces.item;
    if (this.$store.state.usuarioActivo.modeD == 0)
      obj = serialize(obj);
    const res = await this.$store.dispatch("apiPost", {
      url: "Interface/DownloadDinamycLayout",
      item: obj
    })
    console.clear();
    console.log(res);
    const a = document.createElement("a"); 
    a.href = "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64," + res.fileContents; 
    a.download = res.fileDownloadName;
    a.click(); 
    a.remove();
},

读取文件没有任何问题 问候

c# excel asp.net-core vue-component filecontentresult
3个回答
0
投票

假设 FTP 上的文件没有损坏,问题是 .xlsx 文件不是文本文件,但

StreamReader
用于读取文本。按原样使用它会损坏任意二进制数据(例如 .xlsx 文件)。

我个人会直接将文件从 FTP 通过您的服务器流式传输到客户端:

public async Task<TransacResult> DownloadFileInterface(Uri serverUri, string fileName)
{
    StreamReader sr;
    byte[] fileContent;
    try
    {
        string ftpUser = GetConfiguration()["SuatKeys:FTPSuatUser"];
        string ftpPassword = GetConfiguration()["SuatKeys:FTPSuatPassword"];

        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
        request.Method = WebRequestMethods.Ftp.DownloadFile;
        request.KeepAlive = false;
        request.Credentials = new NetworkCredential(ftpUser, ftpPassword);
        
        Stream ftpFileStream = request.GetResponse().GetResponseStream();
        var fileContentResult = new FileStreamResult(ftpFileStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
        {
            FileDownloadName = fileName + ".xlsx"
        };
        return new TransacResult(true, fileContentResult);
    }
    catch (Exception ex)
    {
        return new TransacResult(false, new Message("SUAT-ERR-C02", MessageCategory.Error, "Conexión rechazada", ex.Message));
    }
}

0
投票

我遇到了这个问题。事实证明,如果您使用某些中间件进行日志记录,它会强制将流转换为与 Excel 不兼容的文本表示形式。

我在这个问题上发现了这一点:https://github.com/dotnet/aspnetcore/issues/3304


-1
投票

我用两个动作尝试了三次:

[HttpPost]
        public FileResult download(IFormFile file)
        {
            var filestream = file.OpenReadStream(); 
            var filestreamreader = new StreamReader(filestream, Encoding.Default);          
            var fileContent1 = Encoding.Default.GetBytes(filestreamreader.ReadToEnd());
            return File(fileContent1, "application/ms-excel", "3.xlsx");
            
        }

[HttpPost]
        public FileResult download1(IFormFile file)
        {
            var filestream = file.OpenReadStream();
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            ExcelPackage package = new ExcelPackage(filestream);
            var fileContent = package.GetAsByteArray();
            return File(fileContent, "application/ms-excel", "3.xlsx");
        }

首先,我尝试读取txt文件和xlsx文件的内容,可以看到我们可以获取txt文件的内容字符串,但无法获取xlsx文件中的字符串

然后我尝试再次使用 EPPlus 从流中获取内容字节并成功 结果:

我推荐EEplus的原因:如果有一天我们想下载带有一些额外信息的xlsx文件,我们可以只添加一些代码,而不是删除代码并重新编写 代码如下;

[HttpPost]
        public FileResult download1(IFormFile file)
        {
            var employeelist = new List<Employee>()
            {
                new Employee(){Id=1,Name="Jhon",Gender="M",Salary=5000},
                new Employee(){Id=2,Name="Graham",Gender="M",Salary=10000},
                new Employee(){Id=3,Name="Jenny",Gender="F",Salary=5000}
            };
            
            var stream = file.OpenReadStream();
            
             
            byte[] fileContent;
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            using (ExcelPackage package = new ExcelPackage(stream))
            {
                // add a new worksheet to the empty workbook
                ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Employee");
                
                //Set the Width and Height
                //worksheet.Column(1).Width = xx;
                //worksheet.Row(1).Height = xx;
                
                //Add the headers

                worksheet.Cells[1, 1].Value = "ID";
                worksheet.Cells[1, 2].Value = "Name";
                worksheet.Cells[1, 3].Value = "Gender";
                worksheet.Cells[1, 4].Value = "Salary (in $)";
                for(int i=0; i< employeelist.Count; i++)
                {
                    worksheet.Cells[i + 2, 1].Value = employeelist[i].Id;
                    worksheet.Cells[i + 2, 2].Value = employeelist[i].Name;
                    worksheet.Cells[i + 2, 3].Value = employeelist[i].Gender;
                    worksheet.Cells[i + 2, 4].Value = employeelist[i].Salary;
                } 
                package.Save(); //Save the workbook.
                fileContent = package.GetAsByteArray();
            }            
            return File(fileContent, "application/ms-excel", "target.xlsx");
        }

结果:

© www.soinside.com 2019 - 2024. All rights reserved.