ASP .NET MVC 5 - Zipando e baixando arquivos


 Neste artigo vou mostrar como podemos compactar arquivos no formato ZIP e fazer o download em aplicações ASP .NET MVC usando a linguagem C#.

Neste artigo vamos criar uma aplicação ASP .NET MVC que vai acessar uma pasta no servidor e exibir uma relação de arquivos que o usuário poderá selecionar, zipar e baixar.

Para isso vamos usar os recursos das classes presentes no namespace System.IO.Compression e System.IO.Compression.ZipFile que serão referenciados no projeto via Nuget.

A classe ZipFile Fornece métodos estáticos para criar, extrair e abrir arquivos zip.

Os métodos para manipular arquivos zip e seus arquivos estão espalhados em três classes: ZipFile, ZipArchive e ZipArchiveEntry.

Para... Uso...
Criar um arquivo zip de um diretório  ZipFile.CreateFromDirectory
Extraia o conteúdo de um arquivo zip para um diretório  ZipFile.ExtractToDirectory
Adicionar novos arquivos em um arquivo zip existente  ZipArchive.CreateEntry
Recuperar um arquivo em um arquivo zip  ZipArchive.GetEntry
Recuperar todos os arquivos em um arquivo zip  ZipArchive.Entries
Para abrir um fluxo para um arquivo individual contida em um arquivo zip  ZipArchiveEntry.Open
Excluir um arquivo de um arquivo zip  ZipArchiveEntry.Delete

Recursos Usados:

Criando o projeto ASP .NET MVC 5

Abra o VS 2017 Community e crie um projeto usando o template Web-> ASP .NET Web Application(.NET Framework) e informe o nome Aspn_ZipFiles;

A seguir marque o template  MVC e marque o item MVC sem autenticação e clique em OK;

A seguir crie duas pastas no projeto:

  1. Arquivos
  2. ArquivosZipados

Na primeira pasta vou incluir alguns arquivos que serão exibidos para serem selecionados e zipados. Na segunda pasta serão colocados os arquivos zipados.

A seguir no menu Tools clique em Manage Nuget Packages for Solution e na guia Browse selecione o pacote: System.IO.Compression, selecione os projetos e clique em Install:

No menu Project clique em Add Reference e inclua uma referência ao namespace : System.IO.Compression.FileSystem no projeto:

Criando o controlador ArquivosController

Clique com o botão direito sobre a pasta Controllers e selecione Add-> Controller;

Selecione o template MVC 5 Controller Empty clique em Add e informe o nome ArquivosController:

A seguir vamos definir o código do controlador conforme abaixo:   

using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Web.Mvc;
namespace Aspn_ZipFiles.Controllers
{
    public class ArquivosController : Controller
    {
        // GET: Arquivos
        public ActionResult Index()
        {
            string[] arquivos = Directory.GetFiles(Server.MapPath("~/Arquivos"));
            List<string> downloads = new List<string>();
            foreach (string arquivo in arquivos)
            {
                downloads.Add(Path.GetFileName(arquivo));
            }
            return View(downloads);
        }
        [HttpPost]
        public ActionResult ProcessaForm(List<string> arquivosSelecionados)
        {
            if (System.IO.File.Exists(Server.MapPath("~/ArquivosZipados/pacoteZIP.zip")))
            {
                System.IO.File.Delete(Server.MapPath("~/ArquivosZipados/pacoteZIP.zip"));
            }
            ZipArchive zip = ZipFile.Open(Server.MapPath("~/ArquivosZipados/pacoteZIP.zip"),
 ZipArchiveMode.Create);
            foreach (string arquivo in arquivosSelecionados)
            {
                zip.CreateEntryFromFile(Server.MapPath("~/Arquivos/" + arquivo), arquivo);
            }
            zip.Dispose();
            return File(Server.MapPath("~/ArquivosZipados/pacoteZIP.zip"),"application/zip", "MacorattiZIP.zip");
        }
    }
}
 

No código acima no método Action Index usamos o método GetFiles() da classe Directory para retornar uma lista de arquivos na pasta Arquivos. Note que será retornado o caminho completo e nome do arquivo para todos os arquivos e por isso usamos o método GetFileName para obter apenas os nomes dos arquivos.

A Action ProcessaForm irá criar o arquivo zipado usando as classes ZipFile e ZipArchieve. Essa Action recebe uma lista de strings que a lista dos valores dos checkboxes exibidos na View.

O método Open() da classe ZipFile é usado para criar um arquivo pacoteZIP.zip na pasta ArquivosZipados.

A seguir um laço foreach itera sobre a lista de arquivos selecionados e para cada arquivo aplicamos o método CreateEntryFromFile inclui o arquivo no pacote de arquivos zipados.

Após todos os arquivos serem empacotados o arquivo e retornado usando o método File().

O arquivo a ser baixado tem o nome MacorattiZIP.zip.

Criando a view Index

Vamos criar agora a view Index para exibir os arquivos da pasta Arquivos e permitir a seleção do usuário e a criação do pacote de arquivos zipados.

Clique com o botão direito no interior da Action Index e a seguir clique em Add View aceitando os valores padrão.

A seguir inclua o código abaixo nesta view:

@model List<string>
<title>Zipar e Baixar Arquivos</title>

<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css” 
rel=”stylesheet">

<style>
    table {
        font-family: arial, sans-serif;
        border-collapse: collapse;
        width: 100%;
    }
    td, th {
        border: 1px solid #dddddd;
        text-align: left;
        padding: 8px;
    }
    tr:nth-child(even) {
        background-color: #dddddd;
    }
    .button {
        background-color: #4CAF50;
        border: none;
        color: white;
        padding: 15px 32px;
        text-align: center;
        text-decoration: none;
        display: inline-block;
        font-size: 16px;
        margin: 4px 2px;
        cursor: pointer;
    }
    .button4 {
        border-radius: 9px;
    }
</style>
<h2>Arquivos</h2>
<link href="~/Scripts/sweetalert.css" rel="stylesheet" />
<script src="~/Scripts/jquery-3.3.1.js"></script>
<script src="~/Scripts/sweetalert.js"></script>
<div align="center">
    <table align="center" border="1" cellpadding="4" cellspacing="4">
        <thead>
            <tr>
                <th style="background-color: Yellow;color: blue">Selecionar</th>
                <th style="background-color: Yellow;color: blue">Nome</th>
            </tr>
        </thead>
        @using (Html.BeginForm("ProcessaForm", "Arquivos", FormMethod.Post, new { @enctype =
 "multipart/form-data" }))
        {
            foreach (string arquivo in Model)
            {
                <tr>
                    <td>
                        <input type="checkbox" id="fileUpload" name="arquivosSelecionados"
 value="@arquivo" />
                    </td>
                    <td style="color: blue">@arquivo</td>
                </tr>
            }
            <tr>
                <td colspan="2">
                    <input type="submit" id="arquivoUploadZip" onclick="return validateData();"
 class="button button4" value="Download" />
                </td>
            </tr>
        }
    </table>
</div>
<script>
    //codigo para validar a checkbox
    function validateData() {
        if ($('[type="checkbox"]').is(':checked')) {
            sweetAlert("Parabéns !!!", "Seu arquivo foi baixado", "success");
            return true;
        }
        else
        {
            sweetAlert("Nada foi selecionado!!", "Selecione pelo menos um arquivo", "error");
            return false;
        }
    }
</script>

Neste código percorremos a lista de arquivos enviados pelo Controller e exibimos uma tabela. O Helper BeginForm() posta o formulário para a Action ProcessaForm().

As caixas de seleção são exibidas com o mesmo nome - arquivosSelecionados - e esse nome deve corresponder ao parâmetro da Action ProcessaForm().

Note que o atributo value das caixas de seleção é configurado para o nome do arquivo. (
value="@arquivo" )

Para dar uma aparência mais amigável usamos um arquivo de script para validar se caixa de seleção estã marcada ou não exibindo uma mensagem usando o Sweet Alert.

Eu fiz alguns ajustes no controlador HomeController para exibir um menu com duas opções e exclui as views About e Contact criadas por padrão.

Agora é só alegria...

Executando o projeto teremos o seguinte resultado apresentando pela view Index do controlador Home:

Clicando na opção Arquivos do menu teremos:

Selecionando os arquivos e clicando no botão Download teremos:

Pegue o projeto aqui : Aspn_ZipFiles.zip (sem as referências)

"Para que não sejamos mais meninos inconstantes, levados em roda por todo o vento de doutrina, pelo engano dos homens que com astúcia enganam fraudulosamente.
Antes, seguindo a verdade em amor, cresçamos em tudo naquele que é a cabeça, Cristo;"
Efésios 4:14,15

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti