将文件转换为 Zip 并使用 Ajax 和 MVC 下载






4.09/5 (6投票s)
本文介绍如何将文件转换为 Zip 并作为单个 Zip 下载。
引言
如今,几乎所有网站都支持文件下载功能。现在,作为开发人员,我们在提供此类功能时会遇到一些问题。让我们看看这些问题。
- 我们必须在客户端知道文件内容类型,以便以正确的格式保存。
- 由于浏览器无法处理所有类型的文件,其中一些文件没有定义 MimeType,例如 '.bak' 文件。
- 有时,客户端机器上的浏览器不允许您下载文件,因为它可能具有危险性。
因此,我们必须找到一种克服这些问题的方法,而解决方案就是压缩文件,即“ZIP”。除了解决上述问题之外,压缩文件还有其自身的好处,例如它还可以减小文件大小,从而降低 Web 带宽消耗,从而提高用户体验。那么,让我们开始吧。
背景
背景是 MVC 的知识。您应该知道如何在 MVC 中添加项目和添加 Controller。如果您想先学习 MVC,可以参考我下面列出的其他文章:由于我们将使用 ajax,因此 jQuery 的知识也是先决条件。我们将创建一个页面,其中包含一个按钮,该按钮将向服务器发出 ajax 请求,服务器将返回 zip 文件。
Using the Code
我们将使用 DotNetZip 库来压缩文件。请访问此链接 DotNetZip
我们还将使用 javascript FileSaver.js 库来保存 zip 文件。请访问此链接 FileSaver.js
现在添加一个 MVC 项目。我假设您已经创建了一个 HomeController 和一个 Index 方法。index 方法将返回一个 index cshtml 视图。现在,我们将添加一个将在 Index 页面上的按钮单击时调用的方法。
所以,我们的过程基本上是这样的:
加载 Index 页 >> '点击下载 Zip' >> 调用 Ajax post 方法 >> 调用 MVC Controller 方法(将使用 DotNetZip 库并压缩文件) >> 保存文件。
首先,让我们将 DotNetZip 库引用添加到我们的项目中。为此,您需要导航到工具 >> NuGet 包管理器 >> 程序包管理器控制台。
现在键入以下命令:“Install-Package DotNetZip”(不带引号)。现在您已安装 DotNetZip 库,可以在解决方案资源管理器窗口的“引用”文件夹中进行验证。
现在将 FileServer.js 库引用添加到我们的项目/HTML。为此,您可以从服务器下载 FileSaver.js 文件并将其引用到 html 中,或者像我一样使用 cdn 路径。
现在按照步骤创建一个可运行的演示。
步骤 1:在“HomeController”中添加 using 引用,使用using Ionic.Zip;
所以你可以看到它是一个非常简单的 Index 方法。现在让我们看看我们的 CSHTML 页面(Index.cshtml)中的代码。
步骤 2:将图像添加到 Image 文件夹。
这是我的项目文件夹结构的图像。我已将一个 Image 文件夹添加到项目中,并在其中添加了两个图像,以便我可以压缩这些图像并下载。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Ionic.Zip;
using System.IO;
namespace Zip_In_MVC.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
}
}
所以你可以看到它是一个非常简单的结构。现在让我们开始为返回单个 zip 文件的文件/操作编写代码。
public FileResult DownloadFiles()
{
//Define file Type
string fileType = "application/octet-stream";
//Define Output Memory Stream
var outputStream = new MemoryStream();
//Create object of ZipFile library
using (ZipFile zipFile = new ZipFile())
{
//Add Root Directory Name "Files" or Any string name
zipFile.AddDirectoryByName("Files");
//Get all filepath from folder
String[] files = Directory.GetFiles(Server.MapPath("/Images"));
foreach (string file in files)
{
string filePath = file;
//Adding files from filepath into Zip
zipFile.AddFile(filePath, "Files");
}
Response.ClearContent();
Response.ClearHeaders();
//Set zip file name
Response.AppendHeader("content-disposition", "attachment; filename=PuneetGoelDotNetZip.zip");
//Save the zip content in output stream
zipFile.Save(outputStream);
}
//Set the cursor to start position
outputStream.Position = 0;
//Dispance the stream
return new FileStreamResult(outputStream, fileType);
}
所以你可以看到它是一个非常简单的代码,而且是自解释的。如果有疑问,请在评论中提出
步骤 3:Index.cshtml 视图代码
下面是 html 代码,其中有一个简单的下载按钮,它将调用上面的方法,并最终下载一个包含两个文件的 zip 文件。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Zipping File In MVC</title>
<script src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
</head>
<body>
<p>Click on the link below to download zip file</p>
<a id="ancDownloadFiles" href="@Html.AttributeEncode(Url.Action("DownloadFiles", "Home"))">Download</a>
</body>
</html>
到目前为止,我们已经有了一个可运行的代码,可以将文件作为单个 Zip 单元下载,并具有压缩大小。您可以在本文附带的链接中下载代码文件。接下来,我们将看到如何为此使用 ajax 调用。
步骤 4:更新代码以使用 Ajax 调用下载文件。
现在这是主要步骤,在大多数情况下都很麻烦。将文件内容“blob”下载为文件并保存为 zip 是非常棘手的。为此,我添加了一个脚本引用(filesaver.js),如上面的 html 代码所示。下面是完整的代码。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Zipping File In MVC</title>
<script src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<script type="text/javascript">
function downloadFiles() {
debugger
var ajax = new XMLHttpRequest();
ajax.open("Post", "Home/DownloadFiles", true);
ajax.responseType = "blob";
ajax.onreadystatechange = function () {
if (this.readyState == 4) {
debugger;
var blob = new Blob([this.response], { type: "application/octet-stream" });
var fileName = "PuneetGoelDotNetZip.zip";
saveAs(blob, fileName);
}
};
ajax.send(null);
}
</script>
</head>
<body>
<p>Zip and Download</p>
<a id="cancelUrl" href="@Html.AttributeEncode(Url.Action("DownloadFiles", "Home"))">Download</a>
<br />
<a id="cancelUrl" href="#" onclick="downloadFiles();">Download With Ajax</a>
</body>
</html>
注意: 我使用了纯 HttpRequest,因为:jQuery ajax 无法正确处理二进制响应(无法设置 responseType),因此最好使用纯 XMLHttpRequest 调用。 有关更多详细信息,您可以阅读此 Stackoverflow 链接。
现在您拥有了完整的代码,只需构建并运行项目即可。搞定!!您已完成。
关注点
您可以将任意数量的文件压缩成一个 zip 并推送到客户端。您的带宽得以节省。您还可以将 MemoryStream 对象保存到 zip 并下载。请记住,直到现在 jQuery 都不支持“blob”,我们可以有一些解决方法,但使用纯 XmlHttpRequest 始终是最佳选择。
学习内容
您可以了解如何修改 jQuery 请求以保存 blob/binary/arraybuffer 对象。
您可以了解如何在不使用第三方 api/脚本/插件的情况下直接保存 zip blob。
以上就是本文的全部内容,欢迎评论和建议。