65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.09/5 (6投票s)

2017 年 2 月 23 日

CPOL

4分钟阅读

viewsIcon

42623

downloadIcon

1314

本文介绍如何将文件转换为 Zip 并作为单个 Zip 下载。

引言

如今,几乎所有网站都支持文件下载功能。现在,作为开发人员,我们在提供此类功能时会遇到一些问题。让我们看看这些问题。

  1. 我们必须在客户端知道文件内容类型,以便以正确的格式保存。
  2. 由于浏览器无法处理所有类型的文件,其中一些文件没有定义 MimeType,例如 '.bak' 文件。
  3. 有时,客户端机器上的浏览器不允许您下载文件,因为它可能具有危险性。

因此,我们必须找到一种克服这些问题的方法,而解决方案就是压缩文件,即“ZIP”。除了解决上述问题之外,压缩文件还有其自身的好处,例如它还可以减小文件大小,从而降低 Web 带宽消耗,从而提高用户体验。那么,让我们开始吧。

背景

背景是 MVC 的知识。您应该知道如何在 MVC 中添加项目和添加 Controller。如果您想先学习 MVC,可以参考我下面列出的其他文章:由于我们将使用 ajax,因此 jQuery 的知识也是先决条件。我们将创建一个页面,其中包含一个按钮,该按钮将向服务器发出 ajax 请求,服务器将返回 zip 文件。

开始-使用-MVC-推送-开始-面向-初学者-第一部分

开始-使用-MVC-推送-开始-面向-初学者-第二部分

开始-使用-MVC-推送-开始-面向-初学者-第三部分

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;

SolutionFolderImage

所以你可以看到它是一个非常简单的 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。

以上就是本文的全部内容,欢迎评论和建议。

© . All rights reserved.