Eu tenho um aplicativo WebApi / MVC para o qual estou desenvolvendo um cliente angular2 (para substituir o MVC). Estou tendo alguns problemas para entender como o Angular salva um arquivo.
A solicitação está ok (funciona bem com o MVC, e podemos registrar os dados recebidos), mas não consigo descobrir como salvar os dados baixados (estou seguindo a mesma lógica deste post ). Tenho certeza de que é estupidamente simples, mas até agora simplesmente não estou entendendo.
O código da função do componente está abaixo. Eu tentei diferentes alternativas, a maneira blob deve ser o caminho a percorrer, tanto quanto eu entendi, mas não há nenhuma função createObjectURL
no URL
. Não consigo nem encontrar a definição de URL
na janela, mas aparentemente ela existe. Se eu usar o FileSaver.js
módulo , recebo o mesmo erro. Acho que isso mudou recentemente ou ainda não foi implementado. Como posso acionar o salvamento do arquivo em A2?
downloadfile(type: string){
let thefile = {};
this.pservice.downloadfile(this.rundata.name, type)
.subscribe(data => thefile = new Blob([data], { type: "application/octet-stream" }), //console.log(data),
error => console.log("Error downloading the file."),
() => console.log('Completed file download.'));
let url = window.URL.createObjectURL(thefile);
window.open(url);
}
Por uma questão de integridade, o serviço que busca os dados está abaixo, mas a única coisa que faz é emitir a solicitação e transmitir os dados sem mapear, se for bem-sucedido:
downloadfile(runname: string, type: string){
return this.authHttp.get( this.files_api + this.title +"/"+ runname + "/?file="+ type)
.catch(this.logAndPassOn);
}
Respostas:
O problema é que o observável é executado em outro contexto; portanto, ao tentar criar a URL var, você tem um objeto vazio e não o blob que deseja.
Uma das muitas maneiras existentes para resolver isso é a seguinte:
Quando a solicitação estiver pronta, chamará a função "downloadFile", definida da seguinte maneira:
o blob foi criado perfeitamente e, portanto, o URL var, se não abrir a nova janela, verifique se você já importou 'rxjs / Rx';
Espero que isso possa ajudá-lo.
fonte
this._reportService.getReport()
e o que ele retorna?getReport()
retornos umthis.http.get(PriceConf.download.url)
Tente isso !
1 - Instale dependências para mostrar salvar / abrir arquivo pop-up
2- Crie um serviço com esta função para recuperar os dados
3- No componente, analise o blob com 'file-saver'
Isso funciona para mim!
fonte
Se você não precisar adicionar cabeçalhos na solicitação, para baixar um arquivo no Angular2, faça um simples :
no seu componente.
fonte
authHttp
!Isto é para pessoas que querem saber como fazê-lo usando HttpClient e economizador de arquivos:
Classe de serviço da API:
Componente:
fonte
Que tal agora?
Eu poderia fazer com isso.
Não é necessário pacote adicional.
fonte
Como mencionado por Alejandro Corredor , é um erro de escopo simples. O
subscribe
é executado de forma assíncrona eopen
deve ser colocado nesse contexto, para que os dados terminem de carregar quando acionarmos o download.Dito isto, existem duas maneiras de fazê-lo. Como os documentos recomendam, o serviço cuida de obter e mapear os dados:
Então, no componente, apenas assinamos e lidamos com os dados mapeados. Existem duas possibilidades. O primeiro , como sugerido no post original, mas precisa de uma pequena correção, como observado por Alejandro:
A segunda maneira seria usar o FileReader. A lógica é a mesma, mas podemos esperar explicitamente pelo FileReader carregar os dados, evitando o aninhamento e resolvendo o problema assíncrono.
Nota: Estou tentando baixar um arquivo do Excel e, mesmo que o download tenha sido acionado (portanto, isso responde à pergunta), o arquivo está corrompido. Veja a resposta a esta postagem para evitar o arquivo corrompido.
fonte
res
no blob e realmente desejares._body
. No entanto,_body
é uma variável privada e não acessível. A partir de hoje.blob()
e.arrayBuffer()
em um objeto de resposta http não foram implementados no Angular 2.text()
ejson()
são as únicas duas opções, mas ambas irão alterar seu corpo. Você encontrou uma solução?<a href=""></a>
para baixar um arquivo.Faça o download da solução * .zip do angular 2.4.x: você deve importar o ResponseContentType de '@ angular / http' e alterar o responseType para o ResponseContentType.ArrayBuffer (por padrão, ResponseContentType.Json)
fonte
Para versões angulares mais recentes:
fonte
Baixar arquivos através do ajax é sempre um processo doloroso e, na minha opinião, é melhor permitir que o servidor e o navegador façam esse trabalho de negociação do tipo de conteúdo.
Eu acho que é melhor ter
para fazer isso. Isso nem exige nenhuma nova abertura de janelas e coisas assim.
O controlador MVC como na sua amostra pode ser como o abaixo:
fonte
Estou usando o Angular 4 com o objeto httpClient 4.3. Modifiquei uma resposta que encontrei no Blog técnico da Js, que cria um objeto de link, o usa para fazer o download e o destrói.
Cliente:
O valor this.downloadUrl foi definido anteriormente para apontar para a API. Estou usando isso para baixar anexos, por isso sei o ID, contentType e nome do arquivo: Estou usando uma API MVC para retornar o arquivo:
A classe de anexo fica assim:
O repositório filerep retorna o arquivo do banco de dados.
Espero que isso ajude alguém :)
fonte
Para quem usa Redux Pattern
Eu adicionei no protetor de arquivo como @Hector Cuevas nomeado em sua resposta. Usando o Angular2 v. 2.3.1, não precisei adicionar o @ types / file-saver.
O exemplo a seguir é baixar um diário como PDF.
As ações do diário
Os efeitos do diário
O serviço de diário
O serviço HTTP
O redutor de diário Embora isso defina apenas os estados corretos usados em nosso aplicativo, eu ainda queria adicioná-lo para mostrar o padrão completo.
Espero que isto seja útil.
fonte
Partilho a solução que me ajudou (qualquer melhoria é muito apreciada)
No seu serviço 'pservice':
Parte do componente :
Na parte do componente, você chama o serviço sem assinar uma resposta. A inscrição para obter uma lista completa dos tipos de mímica do openOffice, consulte: http://www.openoffice.org/framework/documentation/mimetypes/mimetypes.html
fonte
Será melhor se você tentar chamar o novo método dentro de você
subscribe
downloadFile(data)
Função interna que precisamos fazerblock, link, href and file name
fonte
Para baixar e mostrar arquivos PDF , um código muito semelhante é o seguinte:
fonte
Aqui está algo que eu fiz no meu caso -
A solução é referenciada aqui - aqui
fonte
Atualize para a resposta de Hector usando o salvador de arquivos e o HttpClient para a etapa 2:
fonte
Eu obtive uma solução para baixar do angular 2 sem ficar corrompido, usando spring mvc e angular 2
1º - meu tipo de retorno é: - ResponseEntity do java end. Aqui estou enviando byte [] array tem tipo de retorno do controlador.
2º - para incluir o salvador de arquivos no seu espaço de trabalho - na página de índice como:
3º - no componente ts escreva este código:
Isso fornecerá o formato de arquivo xls. Se você quiser outros formatos, altere o tipo de mídia e o nome do arquivo com a extensão correta.
fonte
Eu estava enfrentando esse mesmo caso hoje, tive que baixar um arquivo pdf como um anexo (o arquivo não deve ser renderizado no navegador, mas baixado). Para conseguir isso, descobri que era necessário obter o arquivo em um Angular
Blob
e, ao mesmo tempo, adicionar umContent-Disposition
cabeçalho na resposta.Este foi o mais simples que pude obter (Angular 7):
Dentro do serviço:
Então, quando preciso fazer o download do arquivo em um componente, posso simplesmente:
ATUALIZAR:
Removida a configuração desnecessária do cabeçalho do serviço
fonte
O código a seguir funcionou para mim
fonte
Até agora, encontrei as respostas que careciam de insight e avisos. Você pode e deve observar incompatibilidades com o IE10 + (se você se importa).
Este é o exemplo completo da parte do aplicativo e da parte do serviço depois. Observe que definimos a observação: "resposta" para capturar o cabeçalho do nome do arquivo. Observe também que o cabeçalho Content-Disposition deve ser definido e exposto pelo servidor; caso contrário, o atual Angular HttpClient não o passará. Adicionei um pedaço de código do dotnet para isso abaixo.
Núcleo Dotnet, com Content-Disposition & MediaType
fonte
fonte
Basta colocar o
url
comohref
como abaixo.fonte
<a href="my_url" download="myfilename">Download file</a>
my_url deve ter a mesma origem, caso contrário será redirecionado para esse local
fonte
Você também pode fazer o download de um arquivo diretamente do seu modelo, no qual usa o atributo de download, e
[attr.href]
pode fornecer um valor de propriedade do componente. Esta solução simples deve funcionar na maioria dos navegadores.Referência: https://www.w3schools.com/tags/att_a_download.asp
fonte
Se você enviar apenas os parâmetros para um URL, poderá fazê-lo desta maneira:
no serviço que recebe os parâmetros
fonte
Esta resposta sugere que você não pode baixar arquivos diretamente com o AJAX, principalmente por razões de segurança. Então, vou descrever o que faço nessa situação,
01. Adicione
href
atributo na sua marca âncora dentro docomponent.html
arquivo,por exemplo: -
02. Execute todas as etapas a seguir
component.ts
para contornar o nível de segurança e exibir a caixa de diálogo Salvar como pop-up,por exemplo: -
fonte
Bem, escrevi um código inspirado em muitas das respostas acima que devem funcionar facilmente na maioria dos cenários em que o servidor envia um arquivo com um cabeçalho de disposição de conteúdo, sem instalações de terceiros, exceto rxjs e angular.
Primeiro, como chamar o código do seu arquivo de componente
Como você pode ver, é basicamente a chamada média de back-end angular, com duas alterações
Depois que o arquivo é buscado no servidor, em princípio, delegar toda a tarefa de salvar o arquivo na função auxiliar, que eu mantenho em um arquivo separado, e importar para o componente que eu precisar
Não há mais nomes de arquivos GUID enigmáticos! Podemos usar qualquer nome que o servidor forneça, sem precisar especificá-lo explicitamente no cliente ou substituir o nome do arquivo fornecido pelo servidor (como neste exemplo). Além disso, é possível alterar facilmente, se necessário, o algoritmo de extração do nome do arquivo da disposição do conteúdo para atender às suas necessidades e tudo o mais permanecerá inalterado - no caso de um erro durante essa extração, ele passará apenas 'nulo' como o nome do arquivo.
Como outra resposta já apontada, o IE precisa de algum tratamento especial, como sempre. Mas com a borda do cromo chegando em alguns meses, não me preocuparia com isso ao criar novos aplicativos (espero). Há também a questão de revogar o URL, mas eu não tenho tanta certeza disso, por isso, se alguém pudesse ajudar nos comentários, isso seria incrível.
fonte
Se uma guia abrir e fechar sem baixar nada, tentei seguir com link de âncora falso e funcionou.
fonte