[英]How to return an Excel file from ASP.NET Core Web API web-app?
在類似的問題中,使用此代碼可以下載 PDF:
我正在測試 Controller 文件夾中的本地文件(.xlsx、.pdf、.zip)。
[HttpGet("downloadPDF")]
public FileResult TestDownloadPCF()
{
HttpContext.Response.ContentType = "application/pdf";
FileContentResult result = new FileContentResult
(System.IO.File.ReadAllBytes("Controllers/test.pdf"), "application/pdf")
{
FileDownloadName = "test.pdf"
};
return result;
}
但是當另一個文件?例如 Excel 文件(.xlsx)或 ZIP 文件(.zip)時,測試無法正常工作。
代碼:
[HttpGet("downloadOtherFile")]
public FileResult TestDownloadOtherFile()
{
HttpContext.Response.ContentType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
FileContentResult result = new FileContentResult(System.IO.File.ReadAllBytes("Controllers/test.xlsx"),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
FileDownloadName = "otherfile"
};
return result;
}
我還使用以下 Content-Type 進行了測試:
得到相同的結果。
返回任何文件類型的正確方法是什么?
感謝您的回答
我的(工作)解決方案:
FileInfo
。這是我的控制器中的內容:
[HttpGet("test")]
public async Task<FileResult> Get()
{
var contentRootPath = _hostingEnvironment.ContentRootPath;
// "items" is a List<T> of DataObjects
var items = await _mediator.Send(new GetExcelRequest());
var fileInfo = new ExcelFileCreator(contentRootPath).Execute(items);
var bytes = System.IO.File.ReadAllBytes(fileInfo.FullName);
const string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Response.ContentType = contentType;
HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
var fileContentResult = new FileContentResult(bytes, contentType)
{
FileDownloadName = fileInfo.Name
};
return fileContentResult;
}
這是我在 Angular2 中的內容:
downloadFile() {
debugger;
var headers = new Headers();
headers.append('responseType', 'arraybuffer');
let url = new URL('api/excelFile/test', environment.apiUrl);
return this.http
.get(url.href, {
withCredentials: true,
responseType: ResponseContentType.ArrayBuffer
})
.subscribe((response) => {
let file = new Blob([response.blob()], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
let fileName = response.headers.get('Content-Disposition').split(';')[1].trim().split('=')[1];
saveAs(file, fileName);
},
err => this.errorHandler.onError(err)
);
}
我有同樣的問題。 我的問題是由客戶端請求引起的,而不是由服務器響應引起的。 我通過向 Get 請求的標頭選項添加響應內容類型來解決它。 這是我在 Angular 2 中的示例。
來自客戶端的請求(Angular 2)**需要 filesaver.js 庫
this._body = '';
let rt: ResponseContentType = 2; // This is what I had to add ResponseContentType (2 = ArrayBuffer , Blob = 3)
options.responseType = rt;
if (url.substring(0, 4) !== 'http') {
url = config.getApiUrl(url);
}
this.http.get(url, options).subscribe(
(response: any) => {
let mediaType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
let blob = new Blob([response._body], { type: mediaType });
let filename = 'test.xlsx';
fileSaver.saveAs(blob, filename);
});
服務器端代碼。 (.net 核心)
[HttpGet("{dataViewId}")]
public IActionResult GetData(string dataViewId)
{
var fileName = $"test.xlsx";
var filepath = $"controllers/test/{fileName}";
var mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
byte[] fileBytes = System.IO.File.ReadAllBytes(filepath);
return File(fileBytes, mimeType, fileName);
}
如果你想看,這里有參考資料。
以下是如何下載文件的示例,您可以模擬下載 Excel 文件的場景:
public IActionResult Index([FromServices] IHostingEnvironment hostingEnvironment)
{
var path = Path.Combine(hostingEnvironment.ContentRootPath, "Controllers", "TextFile.txt");
return File(System.IO.File.OpenRead(path), contentType: "text/plain; charset=utf-8", fileDownloadName: "Readme.txt");
}
如果文件在wwwroot
文件夾中,您可以執行以下操作:
public IActionResult Index()
{
return File(virtualPath: "~/TextFile.txt", contentType: "text/plain; charset=utf-8", fileDownloadName: "Readme.txt");
}
你可以使用 NPOI
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System.Collections.Generic;
using System.IO;
namespace export_excel.Controllers
{
[ApiController]
[Route("[controller]")]
public class ExportExcelController : ControllerBase
{
private readonly IHostingEnvironment _hostingEnvironment;
public ExportExcelController(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
// https://localhost:5001/ExportExcel/Export
// https://localhost:5001/static-file/employee.xlsx
[HttpGet]
[Route("Export")]
public IActionResult Export()
{
List<Employee> list = new List<Employee>()
{
new Employee{ emp_code = "152110032", Name = "Nguyen Hong Anh", Phone = "0909998789" },
new Employee{ emp_code = "152110055", Name = "Tran Phuong Dung", Phone = "0909993456" },
new Employee{ emp_code = "152110022", Name = "Do Bich Ngoc", Phone = "0909991237" },
new Employee{ emp_code = "152110025", Name = "Tran Thu Ha", Phone = "0909990987" },
};
// New workbook.
XSSFWorkbook wb = new XSSFWorkbook();
// New worksheet.
ISheet sheet = wb.CreateSheet();
// Write to sheet.
// Tạo row
var row0 = sheet.CreateRow(0);
// At first row, merge 3 columns.
// Create cell before merging.
row0.CreateCell(0);
CellRangeAddress cellMerge = new CellRangeAddress(0, 0, 0, 2);
sheet.AddMergedRegion(cellMerge);
row0.GetCell(0).SetCellValue("Employee information");
// Ghi tên cột ở row 1
var row1 = sheet.CreateRow(1);
row1.CreateCell(0).SetCellValue("emp_code");
row1.CreateCell(1).SetCellValue("fullname");
row1.CreateCell(2).SetCellValue("Phone");
// Traversaling array, then write continous.
int rowIndex = 2;
foreach (var item in list)
{
// Init new row.
var newRow = sheet.CreateRow(rowIndex);
// set values.
newRow.CreateCell(0).SetCellValue(item.emp_code);
newRow.CreateCell(1).SetCellValue(item.Name);
newRow.CreateCell(2).SetCellValue(item.Phone);
// Increase index.
rowIndex++;
};
if (!System.IO.File.Exists("c:\\myfiles\\employee.xlsx"))
{
FileStream fs = new FileStream(@"c:\myfiles\employee.xlsx", FileMode.CreateNew);
wb.Write(fs);
}
var path = Path.Combine(@"c:\myfiles\employee.xlsx");
return File(System.IO.File.OpenRead(path), contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8", fileDownloadName: "employee.xlsx");
}
}
public class Employee
{
public string emp_code;
public string Name;
public string Phone;
}
}
文件啟動Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using System.IO;
namespace export_excel
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
// Path.Combine(env.ContentRootPath, @"c:\audio\")),
// Path.Combine(@"c:\audio\")),
Path.Combine(@"c:\myfiles")),
RequestPath = "/static-file"
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
您可以使用 2 種方式中的一種,請轉到
https://localhost:5001/ExportExcel/Export
或
https://localhost:5001/static-file/employee.xlsx
// imports
import * as FileSaver from "file-saver";
import axios from "axios";
export default function App() {
// function to download file
const downloadExcelFileFun = () => {
axios
.post(
`https://yourapp.test.com/api/v1/myexcelfile/demoExcelfile`,
{
// api payload data if any
},
{
headers: {
Authorization: `Bearer TOKEN_STRING`,
},
responseType: "blob",
}
)
.then((res) => {
// the res.data is of type blob
FileSaver.saveAs(res.data, "exampleFile.xlsx");
});
};
return (
<div className="App">
<button
onClick={() => {
downloadExcelFileFun();
}}
>
Download xLsx File
</button>
</div>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.