Tu consegue imprimir no console os dados do arquivo que são retornados do serviço?
Consigo.
Mas não seria o que está na imagem Retorno do backend ?
1 curtida
Falta de atenção minha. Aquele conteudo do atributo arquivo é um base64, certo?
Se for, vc pode seguir os passos desse link que vc deve conseguir: https://medium.com/@riccardopolacci/download-file-in-javascript-from-bytea-6a0c5bb3bbdb
Da forma vc vc está fazendo, funcionaria se vc estivesse retornando o arquivo sem ser na base64.
Como teria que retornar ?
Retorna os bytes do arquivo apenas. Mas como base64 tb funciona, soh que vc teria que fazer uma conversão (conforme o link que mandei - tem a ver com a função atob).
Retorna uma arquivo corrompida.
Este é a classe que retorna com as informações do arquivo
public class ArquivosDTO {
private Long id;
private String nome;
private String contentType;
private byte[] arquivo;
private Long tamanho;
}
Ao fazer o download, ele abre assim.
Será que o problema está no envio dos arquivos ?
Meu incluir está assim:
service
incluir(orcamento: IOrcamentoIncluirModel, files: File[]): Observable<EntityResponseType> {
const orcamentoIncluir = 'dto';
const filesServer = 'files';
const formData: FormData = new FormData();
if(files !== undefined) {
for (let i = 0; i < files.length; i++) {
const blob: Blob = new Blob([JSON.stringify(orcamento)], {type: 'application/json'});
formData.append(orcamentoIncluir, blob);
formData.append(filesServer, files[i]);
}
}
return this.http
.post<IOrcamentoIncluirModel>(this.api + 'incluir', formData, { observe: 'response' })
.pipe(map((res: EntityResponseType) => this.convertDataParaServidor(res)));
}
Java
endpont
@PostMapping(value = "incluir")
@PreAuthorize("hasAuthority('" + ADMINISTRADOR + "') ")
public ResponseEntity<?> incluir(@Valid @RequestPart OrcamentoIncluirDTO dto,
@RequestPart Collection<MultipartFile> files) {
try {
log.info("Metodo que inclui um orcamento");
OrcamentoDTO orcamento = service.incluir(dto, files);
log.info("Com o id: " + orcamento.getId());
orcamento.setMensagem(mensagemSalvar(false));
return new ResponseEntity<>(orcamento, OK);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new BadRequestAlertException(e.getMessage(), ORCAMENTO, null);
}
}
Serviço
private Collection<OrcamentoAnexo> ajustesAnexos(Collection<MultipartFile> anexos, Orcamento orcamento) {
log.info("Metodo que faz ajustes em anexos para o orçamento");
Collection<OrcamentoAnexo> anexosBanco = new ArrayList<>();
if (anexos != null && !anexos.isEmpty()) {
anexos.forEach(anexo -> {
OrcamentoAnexo anexoBanco;
try {
anexoBanco = OrcamentoAnexo.builder().tamanho(anexo.getSize()).arquivo(anexo.getBytes())
.nome(anexo.getOriginalFilename()).orcamento(orcamento).contentType(anexo.getContentType())
.build();
anexosBanco.add(anexoBanco);
aplicacaoAuditoria(anexoBanco);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
});
log.info("Total de anexos: " + anexos.size());
}
return anexosBanco;
}
No Java a não ser o anexo.getBytes(), o restante está chegando correto.
No angular alterei e ficou assim:
download(idArquivo: number, tipo: string): void {
this.arquivosService.downloadArquivoOrcamento(idArquivo).subscribe(
(data: any) => {
const blob = new Blob([data.arquivo], { type: tipo });
const fileName = data.nome;
if (navigator.msSaveBlob) {
// IE 10+
navigator.msSaveBlob(blob, fileName);
} else {
const link = document.createElement('a');
// Browsers that support HTML5 download attribute
if (link.download !== undefined) {
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', fileName);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
},
err => {
alert("Problem while downloading the file.");
console.error(err);
}
)
}
Essa é uma classe que uso para fazer download de base64:
export default class DownloadUtils {
static MYME_TYPE_PDF = 'application/pdf';
static baixarDocumentoBase64Pdf(conteudo, nomeArquivo) {
DownloadUtils.baixarDocumentoBase64(conteudo, nomeArquivo, DownloadUtils.MYME_TYPE_PDF);
}
static baixarDocumentoBase64(conteudo, nomeArquivo, mymeType) {
const blob = DownloadUtils.b64toBlob(conteudo, mymeType);
const blobUrl = URL.createObjectURL(blob);
const downloadLink = document.createElement('a');
downloadLink.href = blobUrl;
downloadLink.download = nomeArquivo;
downloadLink.click();
downloadLink.remove();
}
static b64toBlob(b64Data, contentType) {
const sliceSize = 512;
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i += 1) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, { type: contentType });
}
}
O segredo está na função b64toBlob, que vai converter o base64 para array de bytes e assim criar o blob corretamente.
1 curtida
Todos testes que fiz funcionaram com todas as extensões.
Obrigado @Lucas_Camara
1 curtida