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....
		}	
	}

Nenhum comentário:

Postar um comentário