使用 asp.net core webapi 导出数据文件
本篇文章我们讲解如何使用 ASP.NET Core WebAPI
导出数据文件。
项目准备
1. 创建 Web API 项目
要使用 .NET CLI
创建一个 Web API
项目,请运行以下命令:
dotnet new webapi -o ExportDataFile
webapi
:模板类型,用于创建Web API
项目。-o ExportDataFile
:指定生成的项目文件夹名称。
创建完成后,进入项目目录并启动开发服务器:
cd ExportDataFile
dotnet run
你的 Web API
应用将在默认端口(如 https://localhost:5001
)运行。
要使用 ASP.NET Core Web API
导出数据文件,可以按照以下步骤操作:
2. 定义数据模型
确保 WeatherForecast
类已经定义,例如:
public sealed class WeatherForecast
{public DateOnly Date { get; set; }public int TemperatureC { get; set; }public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);public string? Summary { get; set; }
}
在你的代码中,还应该有一个字符串数组 Summaries
,比如:
private static readonly string[] Summaries =
["Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
];
模拟数据源,方法如下:
private IEnumerable<WeatherForecast> GetWeatherForecasts(int count) => Enumerable.Range(1, 5).Select(index => new WeatherForecast
{Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),TemperatureC = Random.Shared.Next(-20, 55),Summary = Summaries[Random.Shared.Next(Summaries.Length)]
});
导出文件示例
1. 创建导出接口(CSV 示例)
你可以添加一个 API
接口,将数据以 CSV
文件的形式返回。示例代码如下:
using ClosedXML.Excel;
using ExportDataFile.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using System.IO.Compression;
using System.Net.Mime;
using System.Text;
using System.Text.Json;[ApiController]
[Route("weather_forecast")]
public class WeatherForecastController : ControllerBase
{[HttpGet("data/export/csv")]public IActionResult ExportCsv(){var data = GetWeatherForecasts(5);string fileName = $"{Guid.NewGuid()}.data.csv";string contentType = $"{MediaTypeNames.Text.Csv};charset=UTF-8";// 构建 CSV 内容StringBuilder csv = new();csv.AppendLine("Date,TemperatureC,TemperatureF,Summary");foreach (var item in data){csv.AppendLine($"{item.Date},{item.TemperatureC},{item.TemperatureF},{item.Summary}");}// 返回 CSV 文件byte[] fileBytes = Encoding.UTF8.GetBytes(csv.ToString());return File(fileBytes, contentType, fileName);}
}
说明:后续的示例均在该控制器里面实现,为了方便拆分讲解,因此只把单个方法提取讲解。
2. 支持其他格式(可选)
如果你希望支持 Excel
格式,可以通过 NuGet
安装如 EPPlus
或 ClosedXML
等库,并生成 .xlsx
文件。
安装 nuget
包:
dotnet add package ClosedXML --version 0.105.0
示例:使用 ClosedXML 生成 Excel 文件
[HttpGet("data/export/excel")]
public IActionResult ExportExcel()
{var data = GetWeatherForecasts(5);string fileName = $"{Guid.NewGuid()}.data.xlsx";string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8";using (var workbook = new XLWorkbook()){var worksheet = workbook.Worksheets.Add("WeatherForecasts");worksheet.Cell(1, 1).Value = "Date";worksheet.Cell(1, 2).Value = "TemperatureC";worksheet.Cell(1, 3).Value = "TemperatureF";worksheet.Cell(1, 4).Value = "Summary";int row = 2;foreach (var item in data){worksheet.Cell(row, 1).Value = item.Date.ToString();worksheet.Cell(row, 2).Value = item.TemperatureC;worksheet.Cell(row, 3).Value = item.TemperatureF;worksheet.Cell(row, 4).Value = item.Summary;row++;}using var stream = new MemoryStream();workbook.SaveAs(stream);var content = stream.ToArray();return File(content, contentType, fileName);}
}
3. 创建导出接口(JSON 示例)
下面介绍两种示例,分别使用 Gzip
和 ZIP
压缩文件,使用 FileStreamResult
流式返回。
3.1 示例:使用 Gzip 流式压缩
/// <summary>
/// 导出 data 的 json 文件
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
[HttpGet("/data/{count}/export/gzip")]
public async Task<IActionResult> ExportGzipAsync([FromRoute] int count)
{logger.LogInformation("开始获取数据");// 1. 模拟获取数据var data = GetWeatherForecasts(count);string fileName = $"{Guid.NewGuid()}.data.json.gz";string contentType = $"{MediaTypeNames.Application.GZip};charset=UTF-8";// 2. 创建内存流和压缩流,确保在 FileStreamResult 使用前保持打开MemoryStream memoryStream = new();using (var gzipStream = new GZipStream(memoryStream, CompressionLevel.Optimal, leaveOpen: true)) // ⚠️ 关键:leaveOpen: trueusing (var streamWriter = new StreamWriter(gzipStream)){var json = JsonSerializer.Serialize(data);await streamWriter.WriteAsync(json);await streamWriter.FlushAsync();}// 重置流位置memoryStream.Seek(0, SeekOrigin.Begin);// 3. 构造响应头Response.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"){FileName = fileName}.ToString();Response.Headers.ContentEncoding = "gzip";// 4. 使用 FileStreamResult 流式返回return new FileStreamResult(memoryStream, contentType){FileDownloadName = fileName};
}
3.2 示例:使用 ZIP 压缩
[HttpGet("/data/{count}/export/zip")]
public async Task<IActionResult> ExportZipAsync([FromRoute] int count)
{logger.LogInformation("开始获取数据");// 1. 模拟获取数据var data = GetWeatherForecasts(count);string fileName = $"{Guid.NewGuid()}.data.json.zip";string contentType = $"{MediaTypeNames.Application.Zip};charset=UTF-8";// 2. 创建内存流并写入 ZIP 压缩内容MemoryStream memoryStream = new();using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: true)){var jsonEntry = archive.CreateEntry("agent_team.json"); // 在 ZIP 中创建一个文件条目using (var entryStream = jsonEntry.Open())using (var streamWriter = new StreamWriter(entryStream)){var json = JsonSerializer.Serialize(data);await streamWriter.WriteAsync(json);await streamWriter.FlushAsync();}}// 重置流位置,确保从头读取memoryStream.Seek(0, SeekOrigin.Begin);// 3. 构造响应头Response.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"){FileName = fileName}.ToString();Response.Headers.ContentEncoding = "zip";// 4. 使用 FileStreamResult 流式返回return new FileStreamResult(memoryStream, contentType){FileDownloadName = fileName};
}
3.3 Gzip & ZIP 的区别
Gzip
和 ZIP
都是常用的文件压缩格式,但它们在使用场景、压缩方式和功能上有显著的区别。以下是两者的主要对比:
特性 | Gzip | ZIP |
---|---|---|
压缩对象 | 通常用于单个文件的压缩 | 支持多个文件和目录的打包与压缩 |
压缩算法 | 使用 DEFLATE 算法 | 同样使用 DEFLATE 算法(也可支持其他) |
文件结构 | 只能压缩单个文件 | 可以压缩多个文件并保留目录结构 |
跨平台支持 | 类 Unix 系统原生支持(如 Linux、macOS ),Windows 需借助第三方工具(如 7-Zip ) | 所有主流操作系统(Windows、Linux、macOS )均原生支持 |
压缩效率 | 压缩率较高 | 压缩率与 Gzip 相当 |
使用场景 | Linux/Unix 系统下的日志压缩、备份等 | Windows 用户常用,适合打包项目源码等 |
命令行工具 | gzip , gunzip | zip , unzip |
是否支持加密 | 不支持 | 支持密码保护 |
兼容性 | 在 Web 传输中广泛使用(HTTP 压缩) | 更适用于通用文件分发、跨平台共享 |
总结
- 如果你只需要压缩一个文件并且注重压缩率和速度,尤其是类
Unix
环境下,可以选择 Gzip。 - 如果你需要压缩多个文件或目录,并且希望保留文件结构,或者需要跨平台兼容性和加密功能,则更适合使用 ZIP。
4. 测试 API
启动项目后,访问以下 URL
来测试导出功能:
- CSV:
http://localhost:5000/data/export/csv
- Excel:
http://localhost:5000/data/export/excel
- Gzip:
http://localhost:5000/data/{count}/export/gzip
- ZIP:
http://localhost:5000/data/{count}/export/zip
说明:浏览器会自动下载对应的文件。
使用 curl
访问举例:
curl -X 'GET' \'http://localhost:5000/data/5/export/zip' \-H 'accept: application/octet-stream' \
Response body
- Download file
Response headers
content-disposition: attachment; filename=96dbfeec-7473-47f2-ac18-a784063ebbac.data.json.zip; filename*=UTF-8''96dbfeec-7473-47f2-ac18-a784063ebbac.data.json.zip content-encoding: zip content-length: 272 content-type: application/zip; charset=UTF-8 date: Fri,27 Jun 2025 08:30:33 GMT server: Kestrel
5. 部署和优化
- 如果是生产环境,请考虑分页、性能优化以及日志记录。
- 可以根据需求扩展为
PDF、JSON
下载等不同格式。 - 对于大文件导出,建议使用异步方式或后台任务处理。
通过以上步骤,你就可以使用 ASP.NET Core Web API
实现数据的导出功能,并结合 GetWeatherForecasts
模拟数据源来生成所需的文件。