我正在尝试从 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();
},
读取文件没有任何问题 问候
假设 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));
}
}
我遇到了这个问题。事实证明,如果您使用某些中间件进行日志记录,它会强制将流转换为与 Excel 不兼容的文本表示形式。
我在这个问题上发现了这一点:https://github.com/dotnet/aspnetcore/issues/3304
我用两个动作尝试了三次:
[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");
}