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

如何将对象列表转换为CSV并压缩?现有代码问题求助

问题分析与解决方案

当前代码的核心问题

  • CSV生成逻辑完全错误:使用BinaryFormatter序列化对象是二进制序列化,生成的是二进制数据,并非文本格式的CSV,这直接导致文件打开后出现乱码、无关内容。
  • 未实现拆分逻辑:循环遍历所有数据但仅生成了一个SourceFile实例,完全未按需求拆分多个CSV文件。
  • Controller存在语法错误:foreach(SourceFile sf in sourceFile)中的sourceFile应为sourceFiles;sd.Extension应为sf.Extension;bytes变量未赋值,最终返回的FileBytes未定义,代码无法正常运行。

最佳实现方案

1. 依赖选择(推荐)

使用CsvHelper库处理CSV序列化,它能自动处理对象到CSV的映射,避免手动拼接的格式错误,NuGet安装命令:Install-Package CsvHelper

2. 修正Service层(实现CSV生成+拆分)

按指定条数拆分数据,为每个子集生成对应的CSV字节流:

using CsvHelper;
using System.Globalization;

public IEnumerable<SourceFile> PrepareData(List<XXXData> data, int splitSize = 1000) // splitSize为每个CSV的最大行数
{
    var result = new List<SourceFile>();
    var archiveName = "Test_";
    int fileIndex = 1;

    // 拆分数据并生成CSV
    for (int i = 0; i < data.Count; i += splitSize)
    {
        var chunk = data.Skip(i).Take(splitSize).ToList();
        
        using (var ms = new MemoryStream())
        using (var writer = new StreamWriter(ms))
        using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csvWriter.WriteHeader<XXXData>();
            csvWriter.NextRecord();
            csvWriter.WriteRecords(chunk);
            writer.Flush();
            
            result.Add(new SourceFile 
            { 
                Name = $"{archiveName}{fileIndex}", 
                Extension = "csv", 
                FileBytes = ms.ToArray() 
            });
            fileIndex++;
        }
    }

    return result;
}

3. 修正Controller层(修复语法错误+完善Zip逻辑)

IActionResult GetDados()
{
    var list = _itensService.GetDadosXXX().ToList();
    var sourceFiles = _itensService.PrepareData(list); // 可自定义拆分大小,如PrepareData(list, 500)

    using (MemoryStream ms = new MemoryStream()) 
    {
        using (ZipArchive zip = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
        {
            foreach(SourceFile sf in sourceFiles) 
            { 
                ZipArchiveEntry zipItem = zip.CreateEntry($"{sf.Name}.{sf.Extension}");

                using (MemoryStream fileMemoryStream = new MemoryStream(sf.FileBytes))
                using (Stream entryStream = zipItem.Open())
                { 
                    fileMemoryStream.CopyTo(entryStream);
                }
            }
        }
        ms.Position = 0;
        var zipBytes = ms.ToArray();
        return File(zipBytes, "application/zip", "ZipArchiveTest.zip");
    }
}

4. 手动实现CSV(不依赖第三方库)

若不想使用第三方库,可手动拼接CSV内容,注意处理特殊字符:

public IEnumerable<SourceFile> PrepareData(List<XXXData> data, int splitSize = 1000)
{
    var result = new List<SourceFile>();
    var archiveName = "Test_";
    int fileIndex = 1;

    // 生成表头
    var header = string.Join(",", typeof(XXXData).GetProperties().Select(p => p.Name));

    for (int i = 0; i < data.Count; i += splitSize)
    {
        var chunk = data.Skip(i).Take(splitSize).ToList();
        var csvContent = new StringBuilder();
        csvContent.AppendLine(header);

        foreach (var item in chunk)
        {
            // 拼接每行数据,处理含逗号/引号的字段
            var fields = typeof(XXXData).GetProperties().Select(p => 
            {
                var value = p.GetValue(item)?.ToString() ?? string.Empty;
                if (value.Contains(',') || value.Contains('"'))
                {
                    return $"\"{value.Replace("\"", "\"\"")}\"";
                }
                return value;
            });
            csvContent.AppendLine(string.Join(",", fields));
        }

        var fileBytes = Encoding.UTF8.GetBytes(csvContent.ToString());
        result.Add(new SourceFile 
        { 
            Name = $"{archiveName}{fileIndex}", 
            Extension = "csv", 
            FileBytes = fileBytes 
        });
        fileIndex++;
    }

    return result;
}

总结

当前思路的核心方向完全错误,错误使用二进制序列化生成CSV,且未实现拆分逻辑。修正后通过正确的CSV序列化(第三方库或手动拼接)+ 数据拆分+ 修复语法错误,即可实现需求。

内容的提问来源于stack exchange,提问作者Pedro Martins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:33:22