<h1 matDialogTitle>Impressão da requisição</h1>
<div mat-dialog-content>
<iframe
width="100%"
height="570px"
[src]="domSanitizer.bypassSecurityTrustResourceUrl(relatorio)"
></iframe>
</div>
<div class="buttons-div">
<button
matTooltip="Fechar"
mat-mini-fab
type="button"
color="primary"
mat-card-icon
(click)="dialogRef.close(false)"
>
<mat-icon>transit_enterexit</mat-icon>
</button>
</div>
código ts
import { HttpClient } from '@angular/common/http';
import { Component, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { DomSanitizer } from '@angular/platform-browser';
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
import { API } from 'app/core/api/erp.api';
import { ErrorService } from 'app/core/service/error.service';
import { environment } from 'environments/environment';
@Component({
selector: 'app-imprimir-requisicao',
templateUrl: './imprimir-requisicao.component.html',
})
export class ImprimirRequisicaoComponent {
public confirmMessage: string;
relatorio: any;
id: number;
constructor(
public domSanitizer: DomSanitizer,
private http: HttpClient,
private errorServiceS: ErrorService,
public dialogRef: MatDialogRef<FuseConfirmDialogComponent>,
@Inject(MAT_DIALOG_DATA) data: any
) {
this.id = data.id;
}
async ngOnInit(): Promise<void> {
await this.imprimir(this.id);
}
private async imprimir(id: number): Promise<void> {
let httpReturn: any;
try {
httpReturn = await this.http
.get(environment.RELATORIO + API + 'requisicao-compra/' + id + '/')
.toPromise();
this.relatorio = 'data:' + httpReturn['contentType'] + ';base64,';
this.relatorio = this.relatorio + httpReturn['arquivo'];
} catch (error: any) {
if (error !== 'undefined') {
this.errorServiceS.error(
'Erro em gerar relatório de requisição de compras !'
);
}
}
}
}
Está abrindo, corretamente.
Só que fica piscando a cada clique na tela
O que pode ser ?
Mudei para ficar assim o html.
<div mat-dialog-content>
<embed
width="100%"
height="570px"
type="{{ contentType }}"
[src]="domSanitizer.bypassSecurityTrustResourceUrl(relatorio)"
/>
</div>
Mas continuou piscando.
Acho que o problema é nesta parte: [src]="domSanitizer.bypassSecurityTrustResourceUrl(relatorio)"
Claro, pois nao ta igual ao exemplo que passei.
Ao invés de
[src]="domSanitizer.bypassSecurityTrustResourceUrl(relatorio)"
Coloque
src="diretamente o endereço do endpoint que retorne o binario do pdf no backend"
Caso for necessário passar parâmetros coloque direto nessa url.
1 curtida
Quando coloco assim:
<embed
width="100%"
height="570px"
type="application/pdf"
src="http://localhost:8600/modulo-relatorio-api/api/cotacao/{{ id }}/"
/>
ou assim:
<embed
width="100%"
height="570px"
type="application/pdf"
src="{{ relatorio }}"
/>
Este segundo no ngOnInit, monta a variável relatorio
async ngOnInit(): Promise<void> {
this.relatorio = environment.RELATORIO + API + 'cotacao/' + this.id + '/';
}
Dá este no console do nagegador
core.js:4610 ERROR Error: unsafe value used in a resource URL context (see http://g.co/ng/security#xss)
at ɵɵsanitizeResourceUrl (core.js:5539)
at elementPropertyInternal (core.js:9099)
at Module.ɵɵpropertyInterpolate1 (core.js:15873)
at ImprimirCotacaoComponent_Template (imprimir-cotacao.component.html:7)
at executeTemplate (core.js:8689)
at refreshView (core.js:8558)
at refreshComponent (core.js:9711)
at refreshChildComponents (core.js:8355)
at refreshView (core.js:8608)
at refreshEmbeddedViews (core.js:9665)
backend, retornando o byte
controller
package br.com.ghnetsoft.comprasfood.relatorio.resource;
import static br.com.ghnetsoft.principal.enuns.TipoMensagemEnum.ERROR;
import static org.springframework.http.HttpStatus.OK;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import br.com.ghnetsoft.comprasfood.relatorio.service.CotacaoService;
import br.com.ghnetsoft.principal.exception.GeralException;
import br.com.ghnetsoft.principal.resource.PrincipalResource;
import io.swagger.annotations.ApiOperation;
@RestController
@RequestMapping("/api/cotacao")
public class CotacaoResource extends PrincipalResource {
private static final long serialVersionUID = 3370601170855459651L;
@Autowired
private CotacaoService service;
@ApiOperation("Imprime uma cotação pelo id")
@GetMapping("{id}")
public ResponseEntity<?> buscarPeloId(@PathVariable Long id) {
try {
return ResponseEntity.status(OK).body(service.imprimir(id));
} catch (GeralException e) {
return erroExceptionComRegra(e, "cotacao");
} catch (Exception e) {
return excecaoGeralSalvar(e, ERROR, "cotacao", "cotação");
}
}
}
service
package br.com.ghnetsoft.comprasfood.relatorio.service;
import static br.com.ghnetsoft.principal.util.DataUtil.DD_MM_YYYY;
import static br.com.ghnetsoft.principal.util.DataUtil.converterLocalDateParaString;
import static br.com.ghnetsoft.principal.util.DataUtil.converterLocalDateTimeJava;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import br.com.ghnetsoft.comprasfood.model.cotacao.Cotacao;
import br.com.ghnetsoft.comprasfood.model.cotacaoitem.CotacaoItem;
import br.com.ghnetsoft.comprasfood.relatorio.dto.CotacaoItemDTO;
import br.com.ghnetsoft.comprasfood.repository.cotacao.CotacaoRepository;
import br.com.ghnetsoft.comprasfood.repository.cotacaoitem.CotacaoItemRepository;
import br.com.ghnetsoft.principal.dto.ArquivoDTO;
import br.com.ghnetsoft.principal.exception.GeralException;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
@Service
public class CotacaoService {
@Autowired
private CotacaoRepository repository;
@Autowired
private CotacaoItemRepository cotacaoItemRepository;
@Value("${url.angular}")
private String urlAngular;
private BigDecimal total;
public byte[] imprimir(Long id) {
try {
Optional<Cotacao> cotacaoExiste = repository.findById(id);
if (cotacaoExiste.isPresent()) {
total = new BigDecimal("0");
JRDataSource dataSource = new JRBeanCollectionDataSource(inserirLista(cotacaoExiste));
Map<String, Object> parametros = new HashedMap<String, Object>();
parametros.put("loja", cotacaoExiste.get().getLoja().getNome());
parametros.put("numero", cotacaoExiste.get().getNumero());
parametros.put("dataValidade", converterLocalDateParaString(
converterLocalDateTimeJava(cotacaoExiste.get().getDataValidade()), DD_MM_YYYY));
parametros.put("status", cotacaoExiste.get().getStatus().getDescricao());
parametros.put("observacao", cotacaoExiste.get().getObservacao());
parametros.put("total", total);
parametros.put("aceitaMarcaSimilar", cotacaoExiste.get().getAceitaMarcaSimilar().getDescricao());
parametros.put("imgParametro", urlAngular + "assets/images/");
return JasperRunManager.runReportToPdf(
this.getClass().getClassLoader().getResourceAsStream("relatorio/cotacao.jasper"), parametros,
dataSource);
} else {
throw new GeralException("Não existe relatório com este registro !");
}
} catch (JRException e) {
e.printStackTrace();
throw new GeralException("Erro ao gerar relatório de Cotação !");
}
}
private Collection<CotacaoItemDTO> inserirLista(Optional<Cotacao> requisicaoExiste) {
Collection<CotacaoItemDTO> itens = new ArrayList<>();
for (CotacaoItem item : cotacaoItemRepository.buscarItensPelaCotacao(requisicaoExiste.get().getId())) {
itens.add(CotacaoItemDTO.builder().marca(item.getMarca()).insumo(item.getInsumo().getNome())
.unidade(item.getUnidade().getNome()).quantidade(item.getQuantidade())
.quantidadeEstoque(item.getQuantidadeEstoque()).ultimoCusto(item.getUltimoCusto()).build());
total = total.add(item.getTotal());
}
return itens;
}
}
O que pode ser ?
Outra forma que fiz, meio que funcionou foi assim:
ngOnInit(): void {
this.service.imprimir(this.id).subscribe((response: any) => {
let file = new Blob([response], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
this.relatorio = fileURL;
});
}
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { API } from 'app/core/api/erp.api';
import { environment } from 'environments/environment';
@Injectable({
providedIn: 'root',
})
export class CotacoesServiceService {
constructor(private http: HttpClient) {}
imprimir(id: number) {
const url = environment.RELATORIO + API + 'cotacao/' + id + '/';
const httpOptions = {
responseType: 'arraybuffer' as 'json',
};
return this.http.get<any>(url, httpOptions);
}
}
Gerou esta URL blob:http://localhost:4200/2ccdd4fe-26c3-424b-93ae-e9de9b2e931a, mas abriu em outra aba o relatório.
Como fazer para esta window abrir este relatório na mesma página ?
Dessa forma nao sei como ajudar. Sempre trabalhei daquela forma que passei, que é bem mais fácil.
Se chamar a url montada direto no browser o pdf vem?