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

基于内存流大小将Excel文件压缩为Zip文件的实现疑问

解决Excel内存流压缩为Zip文件的问题

原代码存在的问题

  • 写完Excel后,stream的位置停留在末尾,未重置到起始位置,导致后续读取流内容为空
  • 创建Zip条目后,未将Excel的流内容写入到Zip条目流中
  • 变量名错误:使用了未定义的memoryStream,实际应为stream
  • ZipArchive的创建逻辑有误,直接使用原Excel流创建Zip会覆盖原有内容,需要单独的流来存储Zip数据

修正后的完整代码

var excelStream = new MemoryStream();
string fileName = "Sheet1.xlsx"; // 定义Zip内的Excel文件名

// 1. 创建Excel文档并写入到内存流
using (SpreadsheetDocument document = SpreadsheetDocument.Create(excelStream, SpreadsheetDocumentType.Workbook))
{
    WorkbookPart workbookPart = document.AddWorkbookPart();
    workbookPart.Workbook = new Workbook();
    WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
    var sheetData = new SheetData();
    worksheetPart.Worksheet = new Worksheet(sheetData);
    Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
    
    var workSheet = new Sheet()
    {
        Id = workbookPart.GetIdOfPart(worksheetPart),
        SheetId = 1,
        Name = "Sheet1"
    };
    sheets.Append(workSheet);
    
    worksheetPart.Worksheet.Save();
    workbookPart.Workbook.Save();
    document.Save();
    // using块会自动处理Close,无需手动调用
}

// 重置Excel流的位置到起始点,准备读取内容
excelStream.Seek(0, SeekOrigin.Begin);
byte[] fileData = excelStream.ToArray();
var fileSize = fileData.Length;

if (fileSize > 1000)
{
    // 创建新内存流存储Zip文件内容
    using (var zipStream = new MemoryStream())
    {
        // 初始化Zip归档
        using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
        {
            // 在Zip中创建Excel条目
            var fileInArchive = archive.CreateEntry(fileName, CompressionLevel.Fastest);
            // 将Excel流内容写入Zip条目
            using (var entryStream = fileInArchive.Open())
            {
                excelStream.Seek(0, SeekOrigin.Begin);
                excelStream.CopyTo(entryStream);
            }
        }
        
        // 将Zip流写入本地文件
        zipStream.Seek(0, SeekOrigin.Begin);
        using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
        {
            zipStream.CopyTo(fileStream);
        }
    }
}

// 释放资源
excelStream.Close();
await excelStream.DisposeAsync();

关键修正点说明

  • 流位置重置:每次读取流前必须用Seek(0, SeekOrigin.Begin)将指针移到起始位置,否则读取不到有效内容
  • 分离流职责:用独立的zipStream存储Zip内容,避免和原Excel流的读写操作冲突
  • 写入Zip条目:通过CopyTo方法将Excel流的内容完整写入到Zip条目的流中,完成压缩逻辑
  • using块优化:利用using块自动管理资源生命周期,避免手动调用Close可能引发的错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:05:55