Baixe vários arquivos com uma única ação


109

Não tenho certeza se isso é possível usando tecnologias padrão da web.

Desejo que o usuário possa baixar vários arquivos em uma única ação. Isto é, clique nas caixas de seleção ao lado dos arquivos e obtenha todos os arquivos que foram verificados.

É possível - se sim, qual estratégia básica você recomenda. Eu sei que posso usar a tecnologia de cometas para criar eventos do lado do servidor que acionam um HttpResponse, mas espero que haja uma maneira mais simples.

Respostas:


60

O HTTP não oferece suporte para mais de um download de arquivo ao mesmo tempo.

Existem duas soluções:

  • Abra x quantidade de janelas para iniciar os downloads de arquivos (isso seria feito com JavaScript)
  • solução preferida criar um script para compactar os arquivos

39
Por que um arquivo zip é a solução preferida ? Ele cria uma etapa extra para o usuário (descompactação).
speedplane

7
Esta página contém javascript que cria um arquivo ZIP. Olha a página que tem um ótimo exemplo. stuk.github.io/jszip
Netsi1964

Uma terceira maneira é encapsular os arquivos em um arquivo SVG. Se os arquivos são exibidos no navegador, o SVG parece ser o melhor caminho.
VectorVortec

4
O próprio HTTP suporta o formato de mensagem multiparte. Mas os navegadores não analisam as respostas multipartes do lado do servidor, mas tecnicamente não há nada difícil em fazer isso.
CMCDragonkai

2
Esta pode ser uma solução excelente com javascript github.com/sindresorhus/multi-download
juananruiz

84

var links = [
  'https://s3.amazonaws.com/Minecraft.Download/launcher/Minecraft.exe',
  'https://s3.amazonaws.com/Minecraft.Download/launcher/Minecraft.dmg',
  'https://s3.amazonaws.com/Minecraft.Download/launcher/Minecraft.jar'
];

function downloadAll(urls) {
  var link = document.createElement('a');

  link.setAttribute('download', null);
  link.style.display = 'none';

  document.body.appendChild(link);

  for (var i = 0; i < urls.length; i++) {
    link.setAttribute('href', urls[i]);
    link.click();
  }

  document.body.removeChild(link);
}
<button onclick="downloadAll(window.links)">Test me!</button>


3
Estou trabalhando com muitos tipos de arquivo, incluindo imagens, e isso funcionou melhor para mim. No entanto, link.setAttribute('download', null);renomeei todos os meus arquivos para null.
tehlivi

7
Não funciona no IE 11, apenas baixa o .jar (último item da lista). Era a solução perfeita :(
Immutable Brick

1
@AngeloMoreira Sim, pelo menos funciona no Edge. Se você tentar baixar vários arquivos no IE em sites do MS, por exemplo , eles geram várias janelas pop-up, então acho que a melhor solução para o IE ainda é de Dmitry Nogin acima .
Matěj Pokorný

1
@tehlivi - Eu encontrei a mesma coisa. Adicione o link.setAttribute('download',filename)interior do loop. Isso permite que você nomeie os arquivos como desejar. Além disso, acredito que precisa ser apenas o nome do arquivo, não incluindo a URL. Acabei enviando dois arrays: um com o URL completo e outro apenas com o nome do arquivo.
PhilMDev

7
Ele não funciona corretamente no Chrome v75, Windows 10: o único arquivo que é baixado é Minecraft.jar.
andreivictor

54

Você pode criar um conjunto temporário de iframes ocultos, iniciar o download por GET ou POST dentro deles, aguardar o início dos downloads e remover os iframes:

<!DOCTYPE HTML>
<html>
<body>
  <button id="download">Download</button> 

  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
  <script type="text/javascript">

     $('#download').click(function() {
       download('http://nogin.info/cv.doc','http://nogin.info/cv.doc');
     });

     var download = function() {
       for(var i=0; i<arguments.length; i++) {
         var iframe = $('<iframe style="visibility: collapse;"></iframe>');
         $('body').append(iframe);
         var content = iframe[0].contentDocument;
         var form = '<form action="' + arguments[i] + '" method="GET"></form>';
         content.write(form);
         $('form', content).submit();
         setTimeout((function(iframe) {
           return function() { 
             iframe.remove(); 
           }
         })(iframe), 2000);
       }
     }      

  </script>
</body>
</html>

Ou, sem jQuery:

 function download(...urls) {
    urls.forEach(url => {
      let iframe = document.createElement('iframe');
      iframe.style.visibility = 'collapse';
      document.body.append(iframe);

      iframe.contentDocument.write(
        `<form action="${url.replace(/\"/g, '"')}" method="GET"></form>`
      );
      iframe.contentDocument.forms[0].submit();

      setTimeout(() => iframe.remove(), 2000);
    });
  }

incrível, mas por alguns motivos os arquivos não estão sendo baixados. Para mim, a razão parece que a página recarrega após a execução do script, parece ser a razão para os arquivos não serem baixados. Alguma pista do que estou fazendo de errado?
Chirag Mehta

Tenho vários problemas com esta solução. No IE, como minha janela pai alterou o document.domain, meu acesso foi negado. Existem vários posts sobre como consertar isso, mas todos parecem hacky. No Chrome, o usuário recebe uma mensagem de aviso informando que o site tenta fazer download de vários arquivos (mas pelo menos funciona). No Firefox, recebo uma caixa de download diferente, mas quando clico em Salvar, não recebo a caixa de diálogo para salvar o arquivo ...
Melanie

Isso não funcionou para mim, porque a caixa de diálogo de arquivo "bloqueia" a exibição de outras caixas de diálogo de salvamento. O que eu fiz foi algo ligeiramente hackeado - a ação mousemove só é registrada depois que a caixa de diálogo do arquivo desaparece, então usei isso - mas não foi testado. Vou adicioná-lo como outra resposta.
Karel Bílek

2
Isso funciona no IE10? Eu entendi: O objeto não suporta propriedade ou método 'escrever'
Hoppe

por que a função retornada (encerramento?) ativada setTimeout()?
robisrob

34

Esta solução funciona em vários navegadores e não dispara avisos. Em vez de criar um iframe, aqui criamos um link para cada arquivo. Isso evita que mensagens de aviso apareçam.

Para lidar com a parte do loop, usamos setTimeout, que é necessário para que funcione no IE.

/**
 * Download a list of files.
 * @author speedplane
 */
function download_files(files) {
  function download_next(i) {
    if (i >= files.length) {
      return;
    }
    var a = document.createElement('a');
    a.href = files[i].download;
    a.target = '_parent';
    // Use a.download if available, it prevents plugins from opening.
    if ('download' in a) {
      a.download = files[i].filename;
    }
    // Add a to the doc for click to work.
    (document.body || document.documentElement).appendChild(a);
    if (a.click) {
      a.click(); // The click method is supported by most browsers.
    } else {
      $(a).click(); // Backup using jquery
    }
    // Delete the temporary link.
    a.parentNode.removeChild(a);
    // Download the next file with a small timeout. The timeout is necessary
    // for IE, which will otherwise only download the first file.
    setTimeout(function() {
      download_next(i + 1);
    }, 500);
  }
  // Initiate the first download.
  download_next(0);
}
<script>
  // Here's a live example that downloads three test text files:
  function do_dl() {
    download_files([
      { download: "http://www.nt.az/reg.txt", filename: "regs.txt" },
      { download: "https://www.w3.org/TR/PNG/iso_8859-1.txt", filename: "standards.txt" },
      { download: "http://qiime.org/_static/Examples/File_Formats/Example_Mapping_File.txt", filename: "example.txt" },
    ]);
  };
</script>
<button onclick="do_dl();">Test downloading 3 text files.</button>


Este é o único aqui que funcionou para mim, já que tenho que oferecer suporte ao IE. Obrigado.
Øystein Amundsen

1
Essa resposta é de ouro. Apenas aquele que funciona em todos os navegadores sem uma mensagem de aviso. Especialmente o IE. Material brilhante
Mukul Goel

Não funcionando no Chrome OSX, ele me pede para permitir download múltiplo, mas mesmo se eu permitir, apenas o primeiro arquivo é baixado e eu ouvi uma quantidade de "bipe" correspondente ao número de arquivos restantes para download
Allan Raquin

2
O botão não faz nada Google Chrome Version 76.0.3809.100 (Official Build) (64-bit).
1934286

1
O botão não funciona no estouro da pilha Execute o snippet de código. Navegador Crome @speedplane
mb

5

A maneira mais fácil seria servir os vários arquivos agrupados em um arquivo ZIP.

Suponho que você possa iniciar vários downloads de arquivo usando um monte de iframes ou pop-ups, mas do ponto de vista da usabilidade, um arquivo ZIP é ainda melhor. Quem deseja clicar nas dez caixas de diálogo "Salvar como" que o navegador abrirá?


3
Sei que sua resposta vem de 2010, mas muitos usuários estão navegando com smartphones hoje em dia, alguns dos quais não podem abrir zips por padrão (um amigo me disse que seu Samsung S4 Active não pode abrir zips).
Hydraxan14

4

Eu concordo que um arquivo zip é uma solução mais limpa ... Mas se você tiver que enviar vários arquivos, aqui está a solução que encontrei. Funciona no IE 9 e superior (possivelmente uma versão inferior também - não testei), Firefox, Safari e Chrome. O Chrome exibirá uma mensagem ao usuário para obter sua concordância para baixar vários arquivos na primeira vez que seu site o usar.

function deleteIframe (iframe) {
    iframe.remove(); 
}
function createIFrame (fileURL) {
    var iframe = $('<iframe style="display:none"></iframe>');
    iframe[0].src= fileURL;
    $('body').append(iframe);
    timeout(deleteIframe, 60000, iframe);             
 }
 // This function allows to pass parameters to the function in a timeout that are 
 // frozen and that works in IE9
 function timeout(func, time) {
      var args = [];
      if (arguments.length >2) {
           args = Array.prototype.slice.call(arguments, 2);
      }
      return setTimeout(function(){ return func.apply(null, args); }, time);
 }
 // IE will process only the first one if we put no delay
 var wait = (isIE ? 1000 : 0);
 for (var i = 0; i < files.length; i++) {  
      timeout(createIFrame, wait*i, files[i]);
 }

O único efeito colateral dessa técnica é que o usuário verá um atraso entre o envio e a exibição da caixa de diálogo de download. Para minimizar este efeito, sugiro que você use a técnica descrita aqui e nesta questão Detectar quando o navegador recebe o download de um arquivo que consiste em definir um cookie com seu arquivo para saber se o download foi iniciado. Você terá que verificar esse cookie no lado do cliente e enviá-lo no lado do servidor. Não se esqueça de definir o caminho correto para o seu cookie ou você não o verá. Você também terá que adaptar a solução para download de vários arquivos.


4

Uma versão jQuery do iframe responde:

function download(files) {
    $.each(files, function(key, value) {
        $('<iframe></iframe>')
            .hide()
            .attr('src', value)
            .appendTo($('body'))
            .load(function() {
                var that = this;
                setTimeout(function() {
                    $(that).remove();
                }, 100);
            });
    });
}

Cada um está procurando uma matriz. Isso funcionará: download(['http://nogin.info/cv.doc','http://nogin.info/cv.doc']);No entanto, isso não funciona para baixar arquivos de imagem.
tehlivi

3

Solução angular:

HTML

    <!doctype html>
    <html ng-app='app'>
        <head>
            <title>
            </title>
            <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
            <link rel="stylesheet" href="style.css">
        </head>
        <body ng-cloack>        
            <div class="container" ng-controller='FirstCtrl'>           
              <table class="table table-bordered table-downloads">
                <thead>
                  <tr>
                    <th>Select</th>
                    <th>File name</th>
                    <th>Downloads</th>
                  </tr>
                </thead>
                <tbody>
                  <tr ng-repeat = 'tableData in tableDatas'>
                    <td>
                        <div class="checkbox">
                          <input type="checkbox" name="{{tableData.name}}" id="{{tableData.name}}" value="{{tableData.name}}" ng-model= 'tableData.checked' ng-change="selected()">
                        </div>
                    </td>
                    <td>{{tableData.fileName}}</td>
                    <td>
                        <a target="_self" id="download-{{tableData.name}}" ng-href="{{tableData.filePath}}" class="btn btn-success pull-right downloadable" download>download</a>
                    </td>
                  </tr>              
                </tbody>
              </table>
                <a class="btn btn-success pull-right" ng-click='downloadAll()'>download selected</a>

                <p>{{selectedone}}</p>
            </div>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
            <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
            <script src="script.js"></script>
        </body>
    </html>

app.js

var app = angular.module('app', []);            
app.controller('FirstCtrl', ['$scope','$http', '$filter', function($scope, $http, $filter){

$scope.tableDatas = [
    {name: 'value1', fileName:'file1', filePath: 'data/file1.txt', selected: true},
    {name: 'value2', fileName:'file2', filePath: 'data/file2.txt', selected: true},
    {name: 'value3', fileName:'file3', filePath: 'data/file3.txt', selected: false},
    {name: 'value4', fileName:'file4', filePath: 'data/file4.txt', selected: true},
    {name: 'value5', fileName:'file5', filePath: 'data/file5.txt', selected: true},
    {name: 'value6', fileName:'file6', filePath: 'data/file6.txt', selected: false},
  ];  
$scope.application = [];   

$scope.selected = function() {
    $scope.application = $filter('filter')($scope.tableDatas, {
      checked: true
    });
}

$scope.downloadAll = function(){
    $scope.selectedone = [];     
    angular.forEach($scope.application,function(val){
       $scope.selectedone.push(val.name);
       $scope.id = val.name;        
       angular.element('#'+val.name).closest('tr').find('.downloadable')[0].click();
    });
}         


}]);

exemplo de trabalho: https://plnkr.co/edit/XynXRS7c742JPfCA3IpE?p=preview


1

Para melhorar a resposta de @Dmitry Nogin: isso funcionou no meu caso.

No entanto, não foi testado, já que não tenho certeza de como a caixa de diálogo de arquivo funciona em várias combinações de sistema operacional / navegador. (Assim, wiki da comunidade.)

<script>
$('#download').click(function () {
    download(['http://www.arcelormittal.com/ostrava/doc/cv.doc', 
              'http://www.arcelormittal.com/ostrava/doc/cv.doc']);
});

var download = function (ar) {
    var prevfun=function(){};
    ar.forEach(function(address) {  
        var pp=prevfun;
        var fun=function() {
                var iframe = $('<iframe style="visibility: collapse;"></iframe>');
                $('body').append(iframe);
                var content = iframe[0].contentDocument;
                var form = '<form action="' + address + '" method="POST"></form>';
                content.write(form);
                $(form).submit();
                setTimeout(function() {    
                    $(document).one('mousemove', function() { //<--slightly hacky!
                        iframe.remove();
                        pp();
                    });
                },2000);
        }
        prevfun=fun; 
      });
      prevfun();   
}
</script>

1

Isso funciona em todos os navegadores (IE11, firefox, Edge, Chrome e Chrome Mobile). Meus documentos estão em vários elementos selecionados. Os navegadores parecem ter problemas quando você tenta fazer isso muito rápido ... Usei um tempo limite.

//user clicks a download button to download all selected documents
$('#downloadDocumentsButton').click(function () {
    var interval = 1000;
    //select elements have class name of "document"
    $('.document').each(function (index, element) {
        var doc = $(element).val();
        if (doc) {
            setTimeout(function () {
                window.location = doc;
            }, interval * (index + 1));
        }
    });
});

Esta é uma solução que usa promessas:

 function downloadDocs(docs) {
        docs[0].then(function (result) {
            if (result.web) {
                window.open(result.doc);
            }
            else {
                window.location = result.doc;
            }
            if (docs.length > 1) {
                setTimeout(function () { return downloadDocs(docs.slice(1)); }, 2000);
            }
        });
    }

 $('#downloadDocumentsButton').click(function () {
        var files = [];
        $('.document').each(function (index, element) {
            var doc = $(element).val();
            var ext = doc.split('.')[doc.split('.').length - 1];

            if (doc && $.inArray(ext, docTypes) > -1) {
                files.unshift(Promise.resolve({ doc: doc, web: false }));
            }
            else if (doc && ($.inArray(ext, webTypes) > -1 || ext.includes('?'))) {
                files.push(Promise.resolve({ doc: doc, web: true }));
            }
        });

        downloadDocs(files);
    });

1

De longe a solução mais fácil (pelo menos no ubuntu / linux):

  • faça um arquivo de texto com os urls dos arquivos para baixar (ou seja, arquivo.txt)
  • coloque o 'arquivo.txt' no diretório onde você deseja baixar os arquivos
  • abra o terminal no diretório de download do lin anterior
  • baixe os arquivos com o comando 'wget -i file.txt'

Funciona como um encanto.


Eu não entendo por que isso está sendo rejeitado. Isso funciona perfeitamente, muito obrigado.
Martin Fürholz

1

Para resolver isso, criei uma biblioteca JS para transmitir vários arquivos diretamente em um zip no lado do cliente. A principal característica exclusiva é que não há limites de tamanho da memória (tudo é transmitido) nem formato zip (usa zip64 se o conteúdo for superior a 4 GB).

Uma vez que não faz compressão, também tem um ótimo desempenho.

Encontre "downzip" no npm ou no github !


1

O script a seguir fez esse trabalho perfeitamente.

var urls = [
'https://images.pexels.com/photos/432360/pexels-photo-432360.jpeg',
'https://images.pexels.com/photos/39899/rose-red-tea-rose-regatta-39899.jpeg'
];

function downloadAll(urls) {


  for (var i = 0; i < urls.length; i++) {
    forceDownload(urls[i], urls[i].substring(urls[i].lastIndexOf('/')+1,urls[i].length))
  }
}
function forceDownload(url, fileName){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = function(){
        var urlCreator = window.URL || window.webkitURL;
        var imageUrl = urlCreator.createObjectURL(this.response);
        var tag = document.createElement('a');
        tag.href = imageUrl;
        tag.download = fileName;
        document.body.appendChild(tag);
        tag.click();
        document.body.removeChild(tag);
    }
    xhr.send();
}

0

Estou procurando uma solução para fazer isso, mas descompactar os arquivos em javascript não foi tão limpo quanto eu gostaria. Decidi encapsular os arquivos em um único arquivo SVG.

Se você tiver os arquivos armazenados no servidor (eu não), pode simplesmente definir o href no SVG.

No meu caso, converterei os arquivos em base64 e os incorporarei ao SVG.

Edit: O SVG funcionou muito bem. Se você vai apenas baixar os arquivos, o ZIP pode ser melhor. Se você vai exibir os arquivos, então o SVG parece superior.


0

Ao usar componentes Ajax, é possível iniciar vários downloads. Portanto, você deve usar https://cwiki.apache.org/confluence/display/WICKET/AJAX+update+and+file+download+in+one+blow

Adicione uma instância de AJAXDownload à sua página ou qualquer outra coisa. Crie um AjaxButton e substitua onSubmit. Crie um AbstractAjaxTimerBehavior e inicie o download.

        button = new AjaxButton("button2") {

        private static final long serialVersionUID = 1L;

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form)
        {
            MultiSitePage.this.info(this);
            target.add(form);

            form.add(new AbstractAjaxTimerBehavior(Duration.milliseconds(1)) {

                @Override
                protected void onTimer(AjaxRequestTarget target) {
                    download.initiate(target);
                }

            });     
        }

Bom download!


javascrpt?!?!?!?!?!
bluejayke

0

Abaixo do código 100% funcionando.

Etapa 1 : colar o código abaixo no arquivo index.html

<!DOCTYPE html>
<html ng-app="ang">

<head>
    <title>Angular Test</title>
    <meta charset="utf-8" />
</head>

<body>
    <div ng-controller="myController">
        <button ng-click="files()">Download All</button>
    </div>

    <script src="angular.min.js"></script>
    <script src="index.js"></script>
</body>

</html>

Etapa 2 : colar o código abaixo no arquivo index.js

"use strict";

var x = angular.module('ang', []);

    x.controller('myController', function ($scope, $http) {
        var arr = [
            {file:"http://localhost/angularProject/w3logo.jpg", fileName: "imageone"},
            {file:"http://localhost/angularProject/cv.doc", fileName: "imagetwo"},
            {file:"http://localhost/angularProject/91.png", fileName: "imagethree"}
        ];

        $scope.files = function() {
            angular.forEach(arr, function(val, key) {
                $http.get(val.file)
                .then(function onSuccess(response) {
                    console.log('res', response);
                    var link = document.createElement('a');
                    link.setAttribute('download', val.fileName);
                    link.setAttribute('href', val.file);
                    link.style.display = 'none';
                    document.body.appendChild(link);
                    link.click(); 
                    document.body.removeChild(link);
                })
                .catch(function onError(error) {
                    console.log('error', error);
                })
            })
        };
    });

NOTA : Certifique-se de que todos os três arquivos que vão baixar serão colocados na mesma pasta junto com os arquivos angularProject / index.html ou angularProject / index.js .


você rilly amasse ayng [o último dobrador de ar] ular para thuis / ???
bluejayke

0

Obter lista de url com a chamada ajax e, em seguida, usar o plugin jquery para baixar vários arquivos paralelos.

  $.ajax({
        type: "POST",
        url: URL,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        data: data,
        async: true,
        cache: false,
        beforeSend: function () {
            blockUI("body");
        },
        complete: function () { unblockUI("body"); },
        success: function (data) {
           //here data --> contains list of urls with comma seperated
            var listUrls= data.DownloadFilePaths.split(',');
            listUrls.forEach(function (url) {
                $.fileDownload(url);
            });
            return false; 
        },
        error: function (result) {
            $('#mdlNoDataExist').modal('show');
        }

    });

0

É assim que eu faço isso. Abro vários ZIP mas também outro tipo de dados (exporto projeto em PDF e ao mesmo tempo muitos ZIPs com documento).

Acabei de copiar parte do meu código. A chamada de um botão em uma lista:

$url_pdf = "pdf.php?id=7";
$url_zip1 = "zip.php?id=8";
$url_zip2 = "zip.php?id=9";
$btn_pdf = "<a href=\"javascript:;\" onClick=\"return open_multiple('','".$url_pdf.",".$url_zip1.",".$url_zip2."');\">\n";
$btn_pdf .= "<img src=\"../../../images/icones/pdf.png\" alt=\"Ver\">\n";
$btn_pdf .= "</a>\n"

Portanto, uma chamada básica para uma rotina JS (regras Vanilla!). aqui está a rotina JS:

 function open_multiple(base,url_publication)
 {
     // URL of pages to open are coma separated
     tab_url = url_publication.split(",");
     var nb = tab_url.length;
     // Loop against URL    
     for (var x = 0; x < nb; x++)
     {
        window.open(tab_url[x]);
      }

     // Base is the dest of the caller page as
     // sometimes I need it to refresh
     if (base != "")
      {
        window.location.href  = base;
      }
   }

O truque é NÃO fornecer o link direto do arquivo ZIP, mas enviá-lo para o navegador. Como isso:

  $type_mime = "application/zip, application/x-compressed-zip";
 $the_mime = "Content-type: ".$type_mime;
 $tdoc_size = filesize ($the_zip_path);
 $the_length = "Content-Length: " . $tdoc_size;
 $tdoc_nom = "Pesquisa.zip";
 $the_content_disposition = "Content-Disposition: attachment; filename=\"".$tdoc_nom."\"";

  header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
  header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");   // Date in the past
  header($the_mime);
  header($the_length);
  header($the_content_disposition);

  // Clear the cache or some "sh..." will be added
  ob_clean();
  flush();
  readfile($the_zip_path);
  exit();

-1
           <p class="style1">



<a onclick="downloadAll(window.links)">Balance Sheet Year 2014-2015</a>

</p>

<script>
 var links = [
  'pdfs/IMG.pdf',
  'pdfs/IMG_0001.pdf',
 'pdfs/IMG_0002.pdf',
 'pdfs/IMG_0003.pdf',
'pdfs/IMG_0004.pdf',
'pdfs/IMG_0005.pdf',
 'pdfs/IMG_0006.pdf'

];

function downloadAll(urls) {
  var link = document.createElement('a');

  link.setAttribute('download','Balance Sheet Year 2014-2015');
  link.style.display = 'none';

  document.body.appendChild(link);

  for (var i = 0; i < urls.length; i++) {
    link.setAttribute('href', urls[i]);
    link.click();
  }

  document.body.removeChild(link);
}
</script>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.