一.前言一.前言一.前言目前接触的项目中,给定的需求是将系统内所有用户的数据整理好,并保存到文件夹内,目的主要是防止用户在实施人员已配置好的基础上由于不熟悉系统,导致的误删或者误操作。减少实施人员的配置工作。我首先想到的就是将数据导入到Excel中,并以各个用户的名称命名文件夹做好分类。vue下实现Excel导入这个我们见的比较多了,当时我也确实实现了下载Excel的功能,但是后续发现保存的文件都在服务器上,那就有一个问题了,实施人员是通过页面点击的一键保存按钮,数据也确实保存了,但是却是在服务器上,如果想实时看到数据呢,是不是还要去服务器上拷贝一份下来。相对来讲确实比较繁琐,所以整理了下载压缩文件到本地的功能,一起看一下怎么实现的吧。1.1.net core 压缩文件1.1.net core 压缩文件思路是在后台将文件夹整体压缩为zip格式的压缩包,并返回文件流到前端,然后前端接收文件流实现浏览器下载的功能。后端代码,将
public async Task DownloadFiles(DownLoadModel input)

{

if (!Directory.Exists(input.pathUrl))

{

throw new UserFriendlyException("当前要下载的文件夹不存在或已删除");

}

var zipFileUrl = _configurationRoot["downLoadUrlConf:downloadZipFileUrl"];

if (File.Exists(zipFileUrl))

{

File.Delete(zipFileUrl);

}

ZipHelper.CreateZip(input.pathUrl, zipFileUrl);

var memoryStream = new MemoryStream();

using (var stream = new FileStream(zipFileUrl, FileMode.Open))

{

await stream.CopyToAsync(memoryStream);

}

memoryStream.Seek(0, SeekOrigin.Begin);

return new FileStreamResult(memoryStream, "application/octet-stream");//文件流方式,指定文件流对应的ContenType。

}
public async Task DownloadFiles(DownLoadModel input)

{

if (!Directory.Exists(input.pathUrl))

{

throw new UserFriendlyException("当前要下载的文件夹不存在或已删除");

}

var zipFileUrl = _configurationRoot["downLoadUrlConf:downloadZipFileUrl"];

if (File.Exists(zipFileUrl))

{

File.Delete(zipFileUrl);

}

ZipHelper.CreateZip(input.pathUrl, zipFileUrl);

var memoryStream = new MemoryStream();

using (var stream = new FileStream(zipFileUrl, FileMode.Open))

{

await stream.CopyToAsync(memoryStream);

}

memoryStream.Seek(0, SeekOrigin.Begin);

return new FileStreamResult(memoryStream, "application/octet-stream");//文件流方式,指定文件流对应的ContenType。

}
public static class ZipHelper

{

///

/// 压缩文件

///


///

///

public static void CreateZip(string sourceFilePath, string destinationZipFilePath)

{

if (sourceFilePath[sourceFilePath.Length - 1] != System.IO.Path.DirectorySeparatorChar)

sourceFilePath += System.IO.Path.DirectorySeparatorChar;


ZipOutputStream zipStream = new ZipOutputStream(File.Create(destinationZipFilePath));

zipStream.SetLevel(6); // 压缩级别 0-9

CreateZipFiles(sourceFilePath, zipStream, sourceFilePath);


zipStream.Finish();

zipStream.Close();

}

///

/// 递归压缩文件

///


/// 待压缩的文件或文件夹路径

///

///

private static void CreateZipFiles(string sourceFilePath, ZipOutputStream zipStream, string staticFile)

{

Crc32 crc = new Crc32();

string[] filesArray = Directory.GetFileSystemEntries(sourceFilePath);

foreach (string file in filesArray)

{

if (Directory.Exists(file))
//如果当前是文件夹,递归

{

CreateZipFiles(file, zipStream, staticFile);

}


else
//如果是文件,开始压缩

{

FileStream fileStream = File.OpenRead(file);


byte[] buffer = new byte[fileStream.Length];

fileStream.Read(buffer, 0, buffer.Length);

string tempFile = file.Substring(staticFile.LastIndexOf("\\") + 1);

ZipEntry entry = new ZipEntry(tempFile);


entry.DateTime = DateTime.Now;

entry.Size = fileStream.Length;

fileStream.Close();

crc.Reset();

crc.Update(buffer);

entry.Crc = crc.Value;

zipStream.PutNextEntry(entry);


zipStream.Write(buffer, 0, buffer.Length);

}

}

}

}
public static class ZipHelper

{

///

/// 压缩文件

///


///

///

public static void CreateZip(string sourceFilePath, string destinationZipFilePath)

{

if (sourceFilePath[sourceFilePath.Length - 1] != System.IO.Path.DirectorySeparatorChar)

sourceFilePath += System.IO.Path.DirectorySeparatorChar;


ZipOutputStream zipStream = new ZipOutputStream(File.Create(destinationZipFilePath));

zipStream.SetLevel(6); // 压缩级别 0-9

CreateZipFiles(sourceFilePath, zipStream, sourceFilePath);


zipStream.Finish();

zipStream.Close();

}

///

/// 递归压缩文件

///


/// 待压缩的文件或文件夹路径

///

///

private static void CreateZipFiles(string sourceFilePath, ZipOutputStream zipStream, string staticFile)

{

Crc32 crc = new Crc32();

string[] filesArray = Directory.GetFileSystemEntries(sourceFilePath);

foreach (string file in filesArray)

{

if (Directory.Exists(file))
//如果当前是文件夹,递归

{

CreateZipFiles(file, zipStream, staticFile);

}


else
//如果是文件,开始压缩

{

FileStream fileStream = File.OpenRead(file);


byte[] buffer = new byte[fileStream.Length];

fileStream.Read(buffer, 0, buffer.Length);

string tempFile = file.Substring(staticFile.LastIndexOf("\\") + 1);

ZipEntry entry = new ZipEntry(tempFile);


entry.DateTime = DateTime.Now;

entry.Size = fileStream.Length;

fileStream.Close();

crc.Reset();

crc.Update(buffer);

entry.Crc = crc.Value;

zipStream.PutNextEntry(entry);


zipStream.Write(buffer, 0, buffer.Length);

}

}

}

}其中CreateZip方法传入一个源文件的路径,一个目标文件的路径,这里我的目标文件设置在appsetting.json里是个临时路径,只为前端当次下载使用。这样我们就在后台将数据以压缩包的形式压缩好,并返回数据流给前端了。1.2 vue 下载压缩文件

icon="el-icon-download"

size="mini"

type="primary"

class="pull-right"

@click="downloadFile"

>下载文件到本地

icon="el-icon-download"

size="mini"

type="primary"

class="pull-right"

@click="downloadFile"

>下载文件到本地
downloadFile() {

this.loading = true;

let postData = { pathUrl: this.filePathMag };

AjaxHelper.post(this.downLoadUrl, postData, {

responseType: "blob",

}).then((res) => {

// 处理返回的文件流

const content = res.data;

const blob = new Blob([content], { type: "application/zip" });

const fileName = this.tenant.name + "配置信息.zip";

if ("download" in document.createElement("a")) {

// 非IE下载

const elink = document.createElement("a");

elink.download = fileName;

elink.style.display = "none";

elink.href = URL.createObjectURL(blob);

document.body.appendChild(elink);

elink.click();

URL.revokeObjectURL(elink.href); // 释放URL 对象

document.body.removeChild(elink);

} else {

// IE10+下载

navigator.msSaveBlob(blob, fileName);

}

this.loading = false;

});

},
downloadFile() {

this.loading = true;

let postData = { pathUrl: this.filePathMag };

AjaxHelper.post(this.downLoadUrl, postData, {

responseType: "blob",

}).then((res) => {

// 处理返回的文件流

const content = res.data;

const blob = new Blob([content], { type: "application/zip" });

const fileName = this.tenant.name + "配置信息.zip";

if ("download" in document.createElement("a")) {

// 非IE下载

const elink = document.createElement("a");

elink.download = fileName;

elink.style.display = "none";

elink.href = URL.createObjectURL(blob);

document.body.appendChild(elink);

elink.click();

URL.revokeObjectURL(elink.href); // 释放URL 对象

document.body.removeChild(elink);

} else {

// IE10+下载

navigator.msSaveBlob(blob, fileName);

}

this.loading = false;

});

},之前下载Excel时,我们传入后端的content-type为"application/json;application/octet-stream",经过测试发现压缩文件不能使用这种content-type,所以我们去掉了。
另外就是const blob = new Blob([content], { type: "application/zip" });这行代码,如果不加,虽然也能下载,但是下载后的压缩包却无法打开,提示压缩不正确或压缩包已损坏。好了,到此压缩文件的下载就完成了,由于我也是第一次遇到压缩文件的下载,经过摸索终于解决了问题。看起来也比较简单,你学会使用了吗?总结总结总结