Como mostrar Java (JSF) gerou PDF diretamente em Adobereader
-
25-09-2019 - |
Pergunta
Estou usando o JSF 2.0 (Eclipse IDE) e tenho um método em um dos meus grãos que gera alguns arquivos PDF usando o Apache Fop 1.0. Quando clico no botão "makepdf" na minha página JSF, o PDF gerado é aberto na mesma janela em que minha página está (e eu tenho que usar o botão 'Voltar' depois de visualizar/salvar/imprimir PDF).
Eu posso alterar isso de uma maneira que, quando o botão "makepdf" é pressionado, a caixa de diálogo Pop-out padrão aparece e me pergunta se desejo salvar o arquivo ou abri-lo com o ADOBERADER.
Existe uma maneira de que, quando clico no meu botão "makepdf", o PDF gerado é aberto diretamente no ADOBERERADER (e ainda tenho minha página JSF e não preciso confirmar nada) ??? Além disso (não é realmente necessário, mas é bom saber), existe uma maneira de abri -lo em uma nova janela ou enviá -la diretamente para a impressora?
Aqui está a parte principal do meu código (eu excluí algumas coisas irrelevantes):
public void makePDF(long contractId, int documentType) {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String basePath = externalContext.getRealPath("/");
try {
fopFactory.setUserConfig(new File(basePath + "/pdf_transform/config/userconfig.xml"));
fopFactory.setBaseURL(basePath);
fopFactory.getFontManager().setFontBaseURL(basePath);
} catch (Exception e) {
e.printStackTrace();
}
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
foUserAgent.setBaseURL(fopFactory.getBaseURL());
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
response.reset();
response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-disposition", "attachment");
BufferedOutputStream output = null;
try {
output = new BufferedOutputStream(response.getOutputStream(), 10240);
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource(xsltfile));
Source src = new DOMSource(makeXML(contract)); // my method
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
} catch (Exception e) {
e.printStackTrace();
}
facesContext.responseComplete();
}`
Quando eu removo response.setHeader("Content-disposition", "attachment");
Ele abre na mesma janela, caso contrário, me pede para salvar ou abrir.
Desde já, obrigado.
Solução
Abrir uma solicitação em uma nova janela não é diretamente uma preocupação da JSF. É mais uma preocupação com HTML.
Adicionar target="_blank"
para o formulário
<h:form target="_blank">
e enviará a solicitação para uma nova guia/janela.
O envio diretamente para a impressora do cliente não é possível sem introduzir algum código de código que é executado no lado do cliente como homem no meio, como um applet.
Outras dicas
Eu tive um problema semelhante e, felizmente, encontrei uma maneira elegante de resolvê -lo. Se alguém tiver uma solução melhor, por favor me avise.
Caso de uso: o usuário insere dados em um formulário gerado por JSF necessário para a criação de PDF (o PDF é gerado a partir de um servlet). Se a validação falhar, as mensagens de erro serão renderizadas, mas se tudo correr bem, o arquivo PDF será aberto em uma nova janela. :-)
Minha solução:
Em um modelo.xhtml (ou o site que define facelets) digite:
<ui:define name="head"> <h:outputScript rendered="#{myBean.pdfDownloadable}"> window.open('#{myBean.pdfUrl}',"pdfWindow","width=800,height=900,left=50,top=10") </h:outputScript> </ui:define>
Seu link de comando no JSF-Form aponta também o método de ação em MyBean (por exemplo, mybean.showpdf ())
- Se os dados do formulário forem válidos e o showpdf () for chamado, você poderá definir o campo PDFDownloadable como true e o mesmo resultado será renderizado novamente, mas desta vez com window.open () nele.
Espero que ajude alguém ..
Se você deseja abrir um pdf diretamente, por favor use
response.setHeader("Content-Disposition", "inline");