如何用C#编写返回Stream的通用文件生成方法
实现通用文件生成方法(CSV/JSON TXT)
核心实现思路
- TXT类型处理:将数据列表直接序列化为JSON字符串,写入内存流返回
- CSV类型处理:按指定字段长度限制生成CSV内容,同时处理CSV特殊字符转义,写入内存流返回
- 全程使用内存流操作,避免本地文件IO,直接返回可用于传输或下载的流对象
完整代码实现
using System.Text; using System.Text.Json; using System.Collections.Generic; public enum FileType { Csv = 0, Txt } // 零件信息实体示例 public class PartDetailInformation { public string PartNumber { get; set; } public int QuantityAvailable { get; set; } public string Description { get; set; } public decimal DealerListPrice { get; set; } public string CurrencyCode { get; set; } } public static class ApiConstants { // CSV表头,按实际需求调整 public const string PartLocatorFileHeader = "制造商代码,零件编号,库存数量,经销商编号,描述,价格,货币代码\n"; } private Stream GetPartLocatorFileData(IEnumerable<PartDetailInformation> partCatalogDetails, FileType fileType, string brandCode, string dealerIdentity, string fileName) { var stream = new MemoryStream(); var writer = new StreamWriter(stream, Encoding.UTF8); try { if (fileType == FileType.Txt) { // 序列化数据为JSON字符串 var jsonOptions = new JsonSerializerOptions { WriteIndented = true }; string jsonContent = JsonSerializer.Serialize(partCatalogDetails, jsonOptions); writer.Write(jsonContent); } else if (fileType == FileType.Csv) { // 写入CSV表头 writer.Write(ApiConstants.PartLocatorFileHeader); foreach (var part in partCatalogDetails) { // 处理每个字段的长度截断与CSV转义 var csvFields = new List<string> { ProcessCsvField(brandCode, 10).ToUpperInvariant(), ProcessCsvField(part.PartNumber, 30), ProcessCsvField(part.QuantityAvailable.ToString(), 10), ProcessCsvField(dealerIdentity, 20), ProcessCsvField(part.Description, 100), ProcessCsvField(part.DealerListPrice.ToString(), 20), ProcessCsvField(part.CurrencyCode, 3) }; writer.WriteLine(string.Join(",", csvFields)); } } writer.Flush(); stream.Position = 0; // 重置流指针至起始位置 return stream; } catch { stream.Dispose(); writer.Dispose(); throw; } } // 辅助方法:截断字段长度并处理CSV特殊字符 private string ProcessCsvField(string input, int maxLength) { if (string.IsNullOrEmpty(input)) return string.Empty; // 截断到指定长度 string truncated = input.Length > maxLength ? input.Substring(0, maxLength) : input; // 包含逗号、引号或换行时,用双引号包裹并转义内部引号 if (truncated.Contains(',') || truncated.Contains('"') || truncated.Contains('\n') || truncated.Contains('\r')) { return $"\"{truncated.Replace("\"", "\"\"")}\""; } return truncated; }
关键细节说明
- JSON序列化:使用.NET内置的
System.Text.Json,如需兼容旧框架可替换为Newtonsoft.Json - CSV格式兼容:补充了特殊字符转义逻辑,避免因字段包含逗号、引号导致CSV格式错误
- 流复用:使用
MemoryStream在内存中生成文件内容,直接返回流对象,适用于Web下载、文件传输等场景 - 参数补全:原代码中未定义的
brandCode、dealerIdentity作为方法参数传入,保证方法的独立性与可复用性
内容的提问来源于stack exchange,提问作者Kamran Khan
相关产品推荐
相关产品推荐

