> 文章列表 > 关于修改压缩包内的文件(Excel...)内容的解决方法

关于修改压缩包内的文件(Excel...)内容的解决方法

关于修改压缩包内的文件(Excel...)内容的解决方法

关于修改压缩包内文件(Excel…)内容的解决方法

前提:

💩 如果能在压缩前就修改完成就不需要修改压缩包内的文件

💩 如果能在压缩前就修改完成就不需要修改压缩包内的文件

💩 如果能在压缩前就修改完成就不需要修改压缩包内的文件

🌵 场景:

A接口的功能是将用户上传的Excel按指定的行列拆分成多个Excel。(同事写的,一时难以看懂)

记录会存到表中,同时拆分完成的多个Excel会被放入一个压缩文件中保存到某一路径。

压缩包供用户下载。

需求很简单:压缩包内的Excel设置自动列宽

  • 解决方法一:

在他的接口逻辑里直接在拆分后直接设置自动列宽…(不如直接让他改)

  • 解决方法二:

在他下载对应压缩包的接口中直接修改压缩包内的Excel文件,这种方法比较直接且好像可行。

开始

压缩包内的excel没有设置自动列宽,如图:

关于修改压缩包内的文件(Excel...)内容的解决方法

获取压缩包内的文件,设置自动列宽很简单,具体实现如下:

static void Main(string[] args){string zipSavePath = @"E:\\资料拆分\\Zip14";string fileName = $@"TestZip";//打开目标压缩包using (var archive = ZipFile.Open($"{ zipSavePath }\\\\{ fileName }.zip", ZipArchiveMode.Update)){foreach (ZipArchiveEntry entry in archive.Entries){Stream stream = entry.Open();XSSFWorkbook wb = new XSSFWorkbook(stream);ISheet sheet = wb.GetSheetAt(0);int col_num = 0;try{while (sheet.GetRow(0).GetCell(col_num) != null)col_num++;}catch (Exception e){// DoNothing}//找到存在的列,设置自动宽度for (int i = 0; i <= col_num; i++)sheet.AutoSizeColumn(i);MemoryStream ms = new MemoryStream();wb.Write(ms, true);//保存后再把流塞回去using (Stream entryStream = entry.Open()){ms.Seek(0, SeekOrigin.Begin);ms.CopyTo(entryStream);ms.Close();}}}using FileStream fs = new FileStream($"{ zipSavePath }\\\\{ fileName }.zip", FileMode.Open, FileAccess.ReadWrite);byte[] buffer = new byte[fs.Length + 1];fs.Read(buffer, 0, (int)fs.Length);}
}

但这种方法会造成Excel文档损坏

关于修改压缩包内的文件(Excel...)内容的解决方法

虽然在Excel自动的修复后可以使用,但终究是不能使用这种方法的。

要避免这种情况,你必须新建压缩包,把Excel一个个修改后直接存在新的压缩包里,毕竟上面的代码改动后还是被流塞进了原来的文件,故会造成一些不知名的损坏。

改良代码:

static void Main(string[] args)
{string zipSavePath = @"E:\\资料拆分\\Zip14";string fileName = $@"TestZip";//防止多从调用创建重复文件File.Delete($@"{ zipSavePath }\\\\{ fileName + "back" }.zip"); //创建新的压缩包ZipArchive NewZip = ZipFile.Open($@"{ zipSavePath }\\\\{ fileName + "back" }.zip",ZipArchiveMode.Create);using (var archive = ZipFile.Open($"{ zipSavePath }\\\\{ fileName }.zip", ZipArchiveMode.Update)){foreach (ZipArchiveEntry entry in archive.Entries){Stream stream = entry.Open();XSSFWorkbook wb = new XSSFWorkbook(stream);ISheet sheet = wb.GetSheetAt(0);int col_num = 0;try{while (sheet.GetRow(0).GetCell(col_num) != null)col_num++;}catch (Exception e){// DoNothing}for (int i = 0; i <= col_num; i++)sheet.AutoSizeColumn(i);MemoryStream ms = new MemoryStream();wb.Write(ms, true);ZipArchiveEntry newNode = NewZip.CreateEntry(entry.Name);//将设置完成的Excel丢到新的压缩包内using (Stream entryStream = newNode.Open()){ms.Seek(0, SeekOrigin.Begin);ms.CopyTo(entryStream);ms.Close();}}}NewZip.Dispose();using FileStream fs = new FileStream($"{ zipSavePath }\\\\{ fileName+"back" }.zip", FileMode.Open, FileAccess.ReadWrite);byte[] buffer = new byte[fs.Length + 1];fs.Read(buffer, 0, (int)fs.Length);
}

关于修改压缩包内的文件(Excel...)内容的解决方法

如果在要在接口中返回压缩包则直接将新压缩包返回即可。