C#中基于日期范围和车辆名生成文件名导出Excel空表问题
问题解决:无数据场景下Excel导出文件名生成异常修复
核心问题分析
- 原代码在查询结果
data为空时,data.FirstOrDefault()返回null,访问.CarName会触发NullReferenceException - 修改后的代码中,
varCar是IEnumerable<string>类型,直接与字符串拼接会输出类型名(如System.Linq.Enumerable+DistinctIterator),完全不符合文件名预期 - 错误逻辑依赖查询结果获取车辆名称,忽略了请求参数本身已携带
CarName或可通过carId单独查询车辆信息的可靠来源
修正后的完整代码
[ApiController] public class CarController(ISender sender, IDataExportService dataExportService, IDbConnection dbConnection) : BaseController { private readonly IDbConnection _dbConnection = dbConnection; /// <summary> /// 获取指定车辆在指定时间范围内的数据并导出为Excel(XLSX)格式 /// URL: /excel/{carId} /// </summary> [HttpGet("excel/{carId:int}")] public async Task<FileStreamResult> CarDataExport(int carId, [FromQuery] ExportAssetDataRequest request, CancellationToken cancellationToken) { var data = await sender.Send(new ExportCarDataDataQuery(carId, request), cancellationToken); // 优先使用请求参数中的车辆名称,为空则通过carId单独查询兜底 var carName = !string.IsNullOrWhiteSpace(request.CarName) ? request.CarName : await GetCarNameById(carId, cancellationToken); // 生成规范格式的文件名:车辆名_日期.xlsx var currentDate = DateOnly.FromDateTime(DateTime.UtcNow); var fileName = $"{carName}_{currentDate:yyyy-MM-dd}.xlsx"; var memoryStream = dataExportService.ExportToExcel(data, fileName); return memoryStream; } /// <summary> /// 通过车辆ID查询车辆名称(兜底逻辑) /// </summary> private async Task<string> GetCarNameById(int carId, CancellationToken cancellationToken) { var sql = "SELECT CarName FROM Cars WHERE Id = @CarId"; var carName = await _dbConnection.QueryFirstOrDefaultAsync<string>(sql, new { CarId = carId }, cancellationToken: cancellationToken); // 兜底值:避免空字符串导致文件名异常 return carName ?? $"未知车辆_{carId}"; } }
关键优化点
- 脱离查询结果依赖:直接使用请求参数
request.CarName作为文件名的车辆名称来源,彻底避免无数据时的空引用问题 - 兜底查询逻辑:如果请求未携带车辆名称,通过
carId单独查询数据库获取,同时设置兜底值(如未知车辆_XXX)确保文件名永远合法 - 规范文件名格式:用字符串插值+日期格式化生成可读性强的文件名(如
特斯拉Model3_2024-05-20.xlsx) - 空数据兼容:确保
IDataExportService.ExportToExcel方法支持处理空集合,生成结构完整的空Excel表格(若之前未实现,需在导出服务中添加空工作表创建逻辑)
内容的提问来源于stack exchange,提问作者Need Help
相关产品推荐
相关产品推荐

