You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 04:05:53