segunda-feira, 29 de julho de 2013

Imprimir Snapshot de Gráficos do Flex no IReport

Dica do dia:

 Olha que maravilha... Esses dias no trabalho eu estava precisando exibir/imprimir  Gráficos do Flex em pdf, e achei uma solução simples... Como eu ja tinha toda uma estrutura disponível e padronizada, resolvi enviar um Snapshot do gráfico para um servlet e utilizar a infra do Jasper para exibi-los.  Como fiz isso? Transformei um bitmap do gráfico em String codificada na base 64 e enviei via post para o servlet, e decodifiquei a String convertendo em um array de bytes para criar uma Image, e por fim passei por parâmetro para o meu relatorio jasper.


//FLEX 
/**
* Esse metodo recebe o parametro ChartBase (seu relatorio) retorna o Snapshot do grafico convertido em uma String.
* É criado BitmapData com as dimensões do gráfico, que codificado (PNGEncoder) em um ByteArray
* e depois codificado na Base 64.	
*/
public function getSnapshot(source :ChartBase):String{
		var bmp:BitmapData;		
		bmp = new BitmapData(source.width,source.height);
		bmp.draw(source);
		
		var encoderMan : PNGEncoder = new PNGEncoder();
		var byteArr:ByteArray = encoderMan.encode(bmp);
		var 64Encoder:Base64Encoder = new Base64Encoder();
		64Encoder.encodeBytes(byteArr);
		return 64Encoder.toString();//flush()
	}
/**
* Aqui eu invoco o método getSnapshot, setando o seu retorno em param.data , e envio via POST(ou GET) para meu servlet ou php
*/
public function sendImageString(chart :ChartBase):void{
		var header:URLRequestHeader = new URLRequestHeader();
		var param:URLVariables = new URLVariables();
		param.data = getSnapshot(chart);
		
		var urlRequest:URLRequest = new URLRequest("MINHA URL");
		urlRequest.requestHeaders.push(header);
		urlRequest.method = URLRequestMethod.POST;
		urlRequest.data = param;
		navigateToURL(urlRequest, "_blank");
	}	
No IReport crie um parâmetro IMG_GRAFICO do tipo java.awt.Image em seu Relatório, e adicione uma Imagem no Details (ou no lugar desejado) e configure suas propriedades como na imagem abaixo, passando o $P{IMG_GRAFICO} na Image Expression. Feito isso no meu Servlet eu precisarei fazer com que eu receba esse parâmetro e converta a String em Image:

//JAVA
public class MeuServlet extends HttpServlet {

	public MeuServlet(){}
	
	
	/**
	* Este metodo recebe o HttpServletRequest e recupera o parâmetro data que contém a imagem transformada em String.
	* Ele decodifica a Base 64 em um byte[] e retorna o ImageIcon.
	* 
	*/
	public ImageIcon converteStringToImage(HttpServletRequest request){
	
		String imageDataString = request.getParameter("data");
		byte[] imageByteArray = decodeImage(imageDataString);
		return new ImageIcon(imageByteArray);
	
	}
	/**
	 * Decodifica a String da imagem na base64 retornando um array de bytes
	 * 
	 * @param dataString
	 *            - a {@link java.lang.String}
	 * @return byte array
	 * @throws IOException
	 */
	public byte[] decodeImage(String dataString) throws IOException {
		BASE64Decoder decoder = new BASE64Decoder();
		return decoder.decodeBuffer(dataString);
		}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		//Map(object,object)  de Parametro que será utilizado pelo Relatorio Jasper.					
	
		ImageIcon imageIcon = converteStringToImage(request,response, this.getServletContext());
		parametros.put("IMG_GRAFICO", imageIcon.getImage()); // Add a Image ao parâmetro do Relatório
		// ... Invocação do Relatório....
		}	
	}

segunda-feira, 8 de julho de 2013

Alterando tipos de extensões de arquivos de exportação do JasperViewer

Esse post foi escrito tão rápido quanto um coice de porco!

 Trata-se de definir algumas extensões de arquivos que o JasperViewer poderá exportar em seu relatório.

O JasperViewer tem a propriedade JRSaveContributor[] (que contém as extensões permitidas na exportação do relatório) que será percorrida, e sua descrição comparada aos elementos do List ALLOWED_FILE_TYPES. Caso não esteja contido, o objeto do JRSaveContributor[] será removido, fazendo com que somente seja exibido as extensões PDF, WORD, XLS, RTF, HTML, CSV ao usuário.
    private final String PDF = "PDF (*.pdf)";

    private final String RTF = "RTF (*.rtf)";

    private final String HTML = "HTML (*.htm, *.html)";

    private final String XLS = "Single sheet XLS (*.xls)";

    private final String CSV = "CSV (*.csv)";

    private final String WORD = "DOCX (*.docx)";

    private final List<String> ALLOWED_FILE_TYPES = Arrays.asList(PDF, WORD, XLS, RTF, HTML, CSV);
    private void setListAllowedFileTypes(JasperViewer viewer) {

        Field jrViewerField;

        try {

            jrViewerField = viewer.getClass().getDeclaredField("viewer");
            jrViewerField.setAccessible(true);

            JRViewer jrViewer = (JRViewer) jrViewerField.get(viewer);

            List<JRSaveContributor> saveOptions = Arrays.asList(jrViewer.getSaveContributors());

            Iterator<JRSaveContributor> it = saveOptions.iterator();

            while (it.hasNext()) {

                JRSaveContributor jsc = it.next();

                if (ALLOWED_FILE_TYPES.contains(jsc.getDescription())) {

                    continue;

                } else {

                    jrViewer.removeSaveContributor(jsc);

                }

            }

        } catch (Exception ex) {

            logger.error(ex.getClass().getName(), ex);

        }

    }