23
Gerando Relatórios Web 1/23 Criando Relatórios Web Índice BIRT . . . . . . . . . . . . . . . . . . . . 2 iReport . . . . . . . . . . . . . . . . . . . . 20 fPDF . . . . . . . . . . . . . . . . . . . . 22 HTML e CSS . . . . . . . . . . . . . . . . . 23 Ribamar FS - http://cursos.ribafs.org

Relatorios Web

Embed Size (px)

Citation preview

Page 1: Relatorios Web

Gerando Relatórios Web 1/23

Criando Relatórios Web

Índice

BIRT . . . . . . . . . . . . . . . . . . . . 2iReport. . . . . . . . . . . . . . . . . . . . 20fPDF . . . . . . . . . . . . . . . . . . . . 22HTML e CSS . . . . . . . . . . . . . . . . . 23

Ribamar FS ­ http://cursos.ribafs.org

Page 2: Relatorios Web

Gerando Relatórios Web 2/23

BIRT (Biseness Intelligence Reporting Tools)

O BIRT é um gerador de relatórios baseado no Eclipse.Muitos recursos e muito fácil de usar.Também possibilita o uso remoto dos relatóiros gerados através de um visualizador com o Tomcat.

Downloads ­ http://www.eclipse.org/birt  (baixar a versão All­In­One)  ­ 156MB

Tutorial ­ http://www.eclipse.org/birt/phoenix/tutorial/ 

Vídeo Tutorial ­ http://download.eclipse.org/birt/downloads/examples/reports/2.1/elements/elements.html http://download.eclipse.org/birt/downloads/examples/reports/2.1/querymod/querymod.htmlhttp://download.eclipse.org/birt/downloads/examples/reports/2.1/lib/CreatingLibrary/CreatingLib.htmlhttp://download.eclipse.org/birt/downloads/examples/reports/2.1/lib/UsingLibrary/UsingLib.htmlhttp://download.eclipse.org/birt/downloads/examples/reports/2.1/lib/UpdatingLibrary/UpdatingLib.htmlhttp://download.eclipse.org/birt/downloads/examples/reports/2.1/subreport/subreport.htmlhttp://download.eclipse.org/birt/downloads/examples/reports/2.1/grouping/grouping.html

Exemplos ­ http://www.eclipse.org/birt/phoenix/examples http://www.eclipse.org/birt/phoenix/examples/reports/ 

Acesso remoto com tomcat ­ http://www.eclipse.org/birt/phoenix/deploy/ 

Integrando com PHP ­ http://www.eclipse.org/birt/phoenix/deploy/usingPHP.php 

Criando Relatórios com o BIRT (Business Intelligence and Report Tools)

O BIRT é um gerador de relatórios aos moldes do Crystal Report e do iReport, que inclusive tem integração com o PHP e outras linguagens server side.

Download ­ http://download.eclipse.org/birt/downloads/ 

Ribamar FS ­ http://cursos.ribafs.org

Page 3: Relatorios Web

Gerando Relatórios Web 3/23

Criar um Novo Relatório 

Criar Projeto do tipo BIRT

File ­ New ­ Project ­ Business Intelligence and Report Tools ­ Report Project

Clicar sobre o nome do Projeto criado com o botão direito e New ­ Report

1 ­ Criando um relatório partindo de um blank report design­ Crie um novo projeto­ Crie um novo Relatório­ Em File name entre com clientes.rptdesign e Next­ Em Report template deixe Blank Report e Finish­ Observe que a janela de Layout (ao centro e à direita) exibe o nome do relatório acima e seu conteúdo está vazio. À esquerda temos a Paleta de Ferramentas para o design do relatório.Logo à direita da Paleta temos a aba Data Explorer, para a conexão com bancos de dados.

Ribamar FS ­ http://cursos.ribafs.org

Page 4: Relatorios Web

Gerando Relatórios Web 4/23

2 ­ Adicionar um Data Source (Fonte de dados) Do tipo JDBC do PostgreSQL, para usar um banco de dados no nosso relatório.

­ Clicar na aba Data Explorer (acima e à direita da Paleta)­ Clicar com botão direito do mouse sobre New DataSource­ Selecionar JDBC Data Source e Next­ Deve antes ter o jdbc para o postgreSQL em algun diretório (baixar de http://jdbc.postgresql.org/download.html)­ Clicar em Manage Drivers­ Clicar em Add e indicar o driver jdbc do portgresql­ Selecionar e clique em OK­ Em Driver Class selecionar o driver correto (org.postgresql.Driver xxx)­ Em Database URL entre com algo como:

jdbc:postgresql://127.0.0.1:5432/estoque­ Digite username e password do banco­ Clique em Test Connection­ Se tudo ok clique em Finish

Obs.: neste exemplo estou usando o SGBD PostgreSQL, mas não existe diferença para o uso com outros SGBDs, apenas exige­se que eles tenham um driver do tipo JDBC.

Para o MySQL o driver JDBC pode ser baixado de:http://dev.mysql.com/downloads/connector/j/5.1.html 

Ribamar FS ­ http://cursos.ribafs.org

Page 5: Relatorios Web

Gerando Relatórios Web 5/23

3 ­ Criar um Data Set (conjunto de registros ou consulta)­ Clicar em Data Sets com o botão direito e New DataSet­ Abaixo de JDBC Data Source clique em Data Source e NextNa caixa de texto contendo o select digite a consulta SQL, como neste exemplo:select nome,emailfrom public.clientes

­ Ao invés de digitar os campos também podemos efetuar duplos clique nos mesmos à esquerda. Ficará assim: 

Para ter uma consulta dinâmica adicione parâmetros assim:"select nome,email from public.clientes WHERE nome LIKE " + params["nome"]­ Clique em Finish. Apenas clique em OK.­ Duplo clique no data set clientesceara à esquerda e clique em Preview Results à esquerda para visualizar os registros e se certificar de que está tudo ok.

Ribamar FS ­ http://cursos.ribafs.org

Page 6: Relatorios Web

Gerando Relatórios Web 6/23

Veja que também existe suporte a JOIN. Basta clicar com o botão direito sobre Data Sets eNew Join Data Set

4 ­ Layout do relatórioTabelas (tables) interagem com todos os registros retornados por um data set. Isto torna fácil a exibição de registros em forma de linhas e colunas.­ Clique na aba Palette­ Arraste o controle Table da paleta e solte no editor de layout à direita. Será perguntado sobre quantas colunas e quantos detalhes.Deixe com 2 e 1 e OK.­ Clique na aba Data Explorer, expanda Data Sets e depois expanda Data Set. As colunas especificadas na consulta aparecem abaixo: nome e email.­ Arraste "nome" para a primeira célula do detalhe da primeira coluna, onde está Detail Row. De forma que fique na segunda linha e apareça o label na primeira.­ Faça o mesmo com a coluna email na segunda coluna em detalhe.

Para mudar a formatação de qualquer componente do relatório apenas selecione e clique no botão abaixo, em Properties ­ Font ou outra formatação.

Clique em Preview para ver como está.Também para uma visualização profissional vá em File ­ View 

Já temos um relatório contendo os dois campos mas sem nenhuma formatação.

5 ­ Ordenando registros

­ Abra o report no layout editor e selecione abaixo properties. No editor clique em Table (abaixo e à esquerda da área da tabela).­ Ao mover o mouse por essa região aparece Table, então clique nesse botão Table. Abaixo aparecerão as propriedades da Tabela.

Ribamar FS ­ http://cursos.ribafs.org

Page 7: Relatorios Web

Gerando Relatórios Web 7/23

­ Clique na Aba Sorting. Clique em Add para adicionar uma expressão. Em Key selecione "nome" e deixe Ascendente.­ Execute o Preview para ver o resultado.

Observe que nomes iniciados com maiúsculas aparecem no início da lista. O BIRT ordena dados tipo string usando códigos UCS2. Em conjuntos de caracteres baseados em ASCII, as letras maiúsculas têm valor semelhante às minúsculas. Para ordenar case­insensitivamente usar:

row["nome"].toUpperCase( ) 

Na expressão para ordenar.

6 ­ Adicionando Título ao Relatório

Para isso usaremos um controle Text e tags HTML.Selecione o controle Text na Paleta e arraste para cima da tabela.

Ao aparecer o diálogo do controle Text onde tem Auto mude para HTML e digite o conteúdo abaixo:

<CENTER><B><span style="font-size: larger"> Relatório de Clientes</B></span><BR> <FONT size="small">Somente para uso interno</FONT><BR><BR> Relatório Gerado em <VALUE-OF>new Date( )</VALUE-OF></CENTER><BR><BR>

Ribamar FS ­ http://cursos.ribafs.org

Page 8: Relatorios Web

Gerando Relatórios Web 8/23

Criação de Relatório com Gráfico de Barras

Crie um novo relatório (rpt_pedidos.rptdesign)Tipo blank report

Crie este pequeno banco para o relatório:

banco - produto

create table produtos(

codigo int primary key,descricao char(45) not null,quantidade int not null

);

insert into produtos values (1, 'Banana prata', 200);insert into produtos values (2, 'Goiaba', 60);insert into produtos values (3, 'Manga Jasmin', 100);insert into produtos values (4, 'Pera', 120);insert into produtos values (5, 'Maçã', 100);insert into produtos values (6, 'Tangerina', 30);insert into produtos values (7, 'Manga Tamaracá', 90);insert into produtos values (8, 'Manga Jasmin', 50);insert into produtos values (9, 'Manga Rosa', 100);insert into produtos values (10, 'Banana Maça', 100);insert into produtos values (11, 'Banana Pacovã',500);insert into produtos values (12, 'Banana Casca Verde', 60);

Crie outro Data Source também o banco estoque. No Driver Class selecione o PostgreSQL.No Driver URL entre novamente:

jdbc:postgresql://127.0.0.1:5432/produto

Criar um novo Data Set com a seguinte consulta:

select descricao, quantidade from produtos order by quantidade desc

Após finalizar o Data set clique na aba da Paleta.

Arraste o controle Chart e solte na região do centro (layout).

Ribamar FS ­ http://cursos.ribafs.org

Page 9: Relatorios Web

Gerando Relatórios Web 9/23

Aceite este tipo de gráfico (Bar) e apenas clique em Next.

Ribamar FS ­ http://cursos.ribafs.org

Page 10: Relatorios Web

Gerando Relatórios Web 10/23

Agora veja que ele já traz selecionado nosso Data Set, com os dois campos abaixo. Clique em Next.

Ribamar FS ­ http://cursos.ribafs.org

Page 11: Relatorios Web

Gerando Relatórios Web 11/23

Agora podemos alterar o título e algumas outras propriedades do gráfico/relatório:

Para alterar o título selecione à esquerda Title e digite o novo Chart Title.Finalize para voltar para o layout.

Ribamar FS ­ http://cursos.ribafs.org

Page 12: Relatorios Web

Gerando Relatórios Web 12/23

Então redimensione o gráfico no layout para ficar mais interessante:

Para visualizar em outros formatos:

Run - View Report

Ribamar FS ­ http://cursos.ribafs.org

Page 13: Relatorios Web

Gerando Relatórios Web 13/23

Criação de Relatório com Gráfico de Pizza

Vamos criar um novo relatório para o mesmo banco, mesmo Data Source e mesmo Data Set.

jdbc:postgresql://127.0.0.1:5432/produto

select descricao, quantidade from produtos order by quantidade desc

Arraste o controle Chart e altere para Pie.

Clique em Next e veja que já traz selecionado nosso Data Set. Caso tivéssemos vários Data Sets deveriamos selecionar o desejado.

Ribamar FS ­ http://cursos.ribafs.org

Page 14: Relatorios Web

Gerando Relatórios Web 14/23

Ribamar FS ­ http://cursos.ribafs.org

Page 15: Relatorios Web

Gerando Relatórios Web 15/23

Ao conluir redimensione o gráfico gerado.

Dica: existe um outro bom gerador de relatórios free e open source semelhante ao BIRT, que é o iReport. Quem interessar pode baixar daqui:

http://jasperforge.org/projects/ireport

Ribamar FS ­ http://cursos.ribafs.org

Page 16: Relatorios Web

Gerando Relatórios Web 16/23

Acesso Remoto aos Relatórios

O BIRT tem um visualizador de relatórios em Java com Tomcat, que permite o acesso remoto aos relatórios gerados:http://pt.wikibooks.org/wiki/Aplicativos_em_PHP/Recursos_Extras/Geradores_de_Relat%C3%B3rios#Utilizando_o_BIRT_com_PHP_ou_simplesmente_via_Web

Utilizando o BIRT com PHP ou simplesmente via Web

Tutorial de Instalação e uso do Tomcat e do BIRT

J2SE Download ­ http://java.sun.com/javase/downloads/index.jsp

Aqui para baixar somente o JDK (baixei o JDK 5.0 Update 9)

https://sdlc2d.sun.com/ECom/EComActionServlet;jsessionid=65966D4F31A5BD1A572B8A9AB6B2BBDB# (Windows)

https://sdlc2d.sun.com/ECom/EComActionServlet;jsessionid=65966D4F31A5BD1A572B8A9AB6B2BBDB# (Linux)

Tomcat Download ­ http://tomcat.apache.org/

Direto na versão 5.5.20 ­ http://tomcat.apache.org/download­55.cgi#5.5.20

http://mirrors.uol.com.br/pub/apache/tomcat/tomcat­5/v5.5.20/bin/apache­tomcat­5.5.20.tar.gz (Linux)

http://mirrors.uol.com.br/pub/apache/tomcat/tomcat­5/v5.5.20/bin/apache­tomcat­5.5.20.exe (Windows)

Caso sua versão do J2SE seja 1.4 baixar também o JDK 1.4 Compatability Package (duprtiot não precisa):

http://mirrors.uol.com.br/pub/apache/tomcat/tomcat­5/v5.5.20/bin/apache­tomcat­5.5.20­compat.tar.gz (Linux)

http://mirrors.uol.com.br/pub/apache/tomcat/tomcat­5/v5.5.20/bin/apache­tomcat­5.5.20­compat.zip (Windows)

Instalação e Configuração do J2SE

Executar

Mover para o diretório /opt

sudo mv jdk­1_5_0_09­linux­i586.bin

chmod u+s

sudo ./jdk­1_5_0_09­linux­i586.bin

Ribamar FS ­ http://cursos.ribafs.org

Page 17: Relatorios Web

Gerando Relatórios Web 17/23

Editar seu script de inicialização para adicionar a variável de ambiente JAVA_HOME:

sudo gedit /etc/bash.bashrc

JAVA_HOME=/opt/jdk1.5.0_09

CLASSPATH=.:$JAVA_HOME/lib/tools.jar

CATALINA_HOME=/home/ribafs/prog/tomcat # antes e após o igual não pode haver espaços

PATH=$JAVA_HOME/bin:$PATH

export JAVA_HOME CLASSPATH PATH CATALINA_HOME

Para surtir efeito restart o ambiente gráfico fazendo um logoff ou Ctrl+Alt+Backspace.

Instalando e configurando o Tomcat

­ Descompactar apache­tomcat­5.5.20.tar.gz

­ Criar a variável de ambiente para o Tomcat:

­ Descompactar o apache­tomcat­5.5.20­compat.tar.gz no raiz do diretório do tomcat /home/ribafs/prog/tomcat

Testando o Tomcat

Apontar o browser para o endereço http://localhost:8080

Administrando o Tomcat

No Windows a instalação via Installer já deixa pronto.

Edite o arquivo /home/ribafs/prog/tomcat/conf/tomcat­users.xml e adicionar última linha abaixo:<?xml version='1.0' encoding='utf­8'?><tomcat­users>  <role rolename="tomcat"/>  <role rolename="role1"/>  <role rolename="manager"/>  <role rolename="admin"/>  <user username="tomcat" password="tomcat" roles="tomcat"/>  <user username="role1" password="tomcat" roles="role1"/>  <user username="both" password="tomcat" roles="tomcat,role1"/>  <user username="admin" password="admin" fullName="Tomcat Administrator" roles="admin,manager"/></tomcat­users>

Com usuário e senha (admin para ambos)

Ribamar FS ­ http://cursos.ribafs.org

Page 18: Relatorios Web

Gerando Relatórios Web 18/23

Abrir no browser em http://127.0.0.1:8080/admin/

Entre com admin e admin

Instalando e usando o Visualizador de Relatórios do BIRT

Download ­ http://download.eclipse.org/birt/downloads/ (procure por Birt Runtime correspondente à versão do seu BIRT):

http://www.eclipse.org/downloads/download.php?file=/birt/downloads/drops/M­R1­2.2M1­200610171021/birt­runtime­2.2M1.zip

Descompactar e copiar o subdiretório WebViewerExample para o diretório /home/ribafs/prog/tomcat/webapps.

Renomear o WebViewerExample para birt­viewer (opcionalmente)

Abra o link no browser http://localhost:8080/manager/html

Entre com admin e admin.

À esquerda clique em /birt­viewer e veja que abre­se o visualizador web de relatórios do BIRT.

Caso deseje abrir um relatório seu já criado, copie para /home/ribafs/prog/tomcat/webapps/birt­viewer e chame no browser assim:

http://localhost:8080/birt­viewer/frameset?__report=seurelatorio.rptdesign&parametro=valordoparametro

Instalando o Driver JDBC do seu SGBD

Copie para a pasta:

birt­viewer/WEB­INF/platform/plugins/org.eclipse.birt.report.data.oda.jdbc_2.2.0.v20061009­0630/drivers

postgresql­8.1­407.jdbc3.jar (no meu caso)

Observe que "v20061009­0630" vai depender da sua versão.

Ribamar FS ­ http://cursos.ribafs.org

Page 19: Relatorios Web

Gerando Relatórios Web 19/23

Abrindo Relatório de Script PHP

Supondo que deseje abrir o relatório "rpt_produtos.rptdesign" na web. Depois de tudo pronto e de ter copiado o relatório para a pasta birt­viewer, basta chamar assim:

<a href=http://localhost:8080/birt_viewer/frameset?__report=rpt_produtos.rptdesign>Relatório</a>

Se preferir formas mais sofisticadas veja estas sugeridas na documentação do BIRT:<?php$fname = "./clientes.rptdesign";// Redirect browser$dest = "http://localhost:8080/birt­viewer/run?__report=";$dest .= urlencode( realpath( $fname ) );header("Location: $dest" );?>

Passando parâmetros<?php$fname = "./clientes.rptdesign";// Redirect browser$dest = "http://localhost:8080/birt­viewer/run?__report=";$dest .= ";sample=" . urlencode( $paramValue );$dest .= urlencode( realpath( $fname ) );header("Location: $dest" );?>

Parâmetros de formulários

Deally, we could use PHP to create a UI form that prompts for the report parameters. The BIRT viewer creates this form in Java using information in the report design. Unfortunately, at present, there is no way to retrieve the raw parameter descriptions from the BIRT viewer using a URL. Instead, there are two alternatives we can use.

First, if we know the parameters ahead of time, we can design a custom form in PHP that prompts the user for them. This works if we have a small number of reports, or if we need to create a specialized parameter page for each report anyway.

Second, we can let the BIRT viewer display the parameter page using the frameset URL. Generating Reports Dynamically

Finally, PHP provides one additional BIRT integration option: the ability to generate report designs dynamically for a specific task. For example, suppose you have a bug tracking system, and you'd like your user to create their own reports via the web. You can ask the user for the columns to display, then use PHP to create a BIRT report design customized to display those columns. PHP is ideal for this: it allows us to insert scripting directly into HTML. Since a BIRT design is XML, and XML is close enough to HTML for PHP, we can "trick" PHP into generating a BIRT report design instead of an HTML page.

To generate a report design, do the following:

• Create a BIRT report design typical of the kind of report you want to create. 

Ribamar FS ­ http://cursos.ribafs.org

Page 20: Relatorios Web

Gerando Relatórios Web 20/23

• Create a PHP template file that contains this design. Insert the contents of the design file in place of the HTML you'd usually put into a PHP file. 

• Redirect PHP's output from the template file into a report design file. • Use PHP to generate BIRT XML for the table headings and cells the user wants. Use your 

report design as a template for what is needed. Consult the ROM spec for details on various elements and properties. 

• Within the data set in your template, create an SQL query that fetches the required columns. (Works with other data set types as well.) 

• Use the code above to redirect the browser to run that report using the BIRT viewer. 

The following PHP code redirects the output of a PHP page, template.inc, into a report design called temp.rptdesign:ob_start( );require "template.inc";$page = ob_get_contents( );ob_end_clean( );$fw = fopen( "temp.rptdesign", "w" );fputs( $fw, $page, strlen( $page ) );fclose( $fw ); 

Opções avançadas

http://localhost:8080/birt­viewer/run?__report=report%5CSalesInvoice.rptdesign&OrderNumber=10010

List of Options

The available viewer options include:Option  Description     Values  Default         frameset        run__format        The output format       html or pdf     html    N       Y__isnull        Identifies that a report parameter has a null value Parameter name  None. Required.         N       Y__locale        Report locale   Java locale value such as en, en­us or ch­zh. JVM locale      Y       Y__report        The path to the report design.          None. Required. Y       Y__document      The path to the report document.                None. Required. Y       NreportParam     Report parameter.       As specified in the report design. As specified in the report design.      Y       Y

Veja os originais para maiores detalhes:

http://www.eclipse.org/birt/phoenix/deploy/viewerSetup.php

http://www.eclipse.org/birt/phoenix/deploy/usingPHP.php

http://www.eclipse.org/birt/phoenix/deploy/viewerUsage.php

Ribamar FS ­ http://cursos.ribafs.org

Page 21: Relatorios Web

Gerando Relatórios Web 21/23

Gerador de Relatório iReportSite oficial ­ http://jasperforge.org/sf/projects/ireport

Ótimo tutorial sobre o iReport, inclusive com o acesso via web (com java)

www.furutani.eti.br/tutoriais/Mini­Tutorial_Relatorios_Java_JasperReports_e_iReport.pdf

Tutorial de iReport

http://www.javafree.org/javabb/viewtopic.jbb?t=3154

Starting with JasperReports by Gregory Beumer

http://technology.amis.nl/blog/index.php?p=346

Manual do iReport

http://jasperforge.org/sf/wiki/do/viewPage/projects.ireport/wiki/IReportManualV1.2.1

iReport Documentação

http://jasperforge.org/sf/wiki/do/viewPage/projects.ireport/wiki/HomePage

Tutorial JasperReports - IReports

HTML ­ http://br.geocities.com/robertofurutani/java/Tutorial_JasperReports/

PDF ­ http://www.furutani.eti.br/tutoriais/Tutorial_Sub_Relatorio_ArrayList.pdf

Fontes ­ http://br.geocities.com/robertofurutani/java/Tutorial_JasperReports/Tutorial.zip

Outro tutorial em português

http://www.livramento.yu.com.br/tutoriais/ireport.html

A Tutorial on Generating Reports by iReport

http://www.cise.ufl.edu/~otopsaka/CIS4301/ReportDemo/

Ribamar FS ­ http://cursos.ribafs.org

Page 22: Relatorios Web

Gerando Relatórios Web 22/23

fPDF  ­  http://www.fpdf.org 

Tutorial ­ http://www.fpdf.org/en/tutorial/index.php Download ­ http://www.fpdf.org/en/download.php Exemplos ­ http://www.fpdf.org/en/script/index.php Manual online ­ http://www.fpdf.org/en/doc/index.php Manual pt­br para download ­ http://www.fpdf.org/en/dl.php?id=97 Tutorial ­ http://www.fpdf.org/en/tutorial/index.php fpdfgenerator ­ http://fpdfgenerator.sourceforge.net/ 

O fPDF é uma alternativa para criação de relatórios em PDF de aplicativos e sites em PHP.Ele dá trabalho, pois precisamos criar cada detalhe do que será exibido mas por outro lado permite um maior controle da tela.

No site oficial existe vários exemplos na seção de scripts, inclusive um desenvolvido por min:http://www.fpdf.org/en/script/script11.php

Aqui também trago um pequeno gerador de código para o fPDF, feito em JavaScript que ajuda na elaboração de relatórios com fPDF, que é o fpdfgenerator, que encontra-se no SourceForge:http://fpdfgenerator.sourceforge.net/

Também trago um exemplo de aplicativo de condomínios que imprime os recibos com fPDF.

Ribamar FS ­ http://cursos.ribafs.org

Page 23: Relatorios Web

Gerando Relatórios Web 23/23

HTML e CSS

O Framework Ágil vem com um pequeno gerador de relatórios com acesso a bancos, em HTML e CSS.

Download ­ http://cursodephp.ribafs.org/down/ferramentas/relatorios/relatorios_htmlcss.zip Framework Ágil ­ http://web.ribafs.org/frameworks/35­framework­agil Descompactar e o gerador de relatórios encontra­se na pasta admin.

Isolei o gerador de relatórios em HTML e CSS do Framework Ágil e estou oferecendo aqui.

Observação: Todas essas ferramentas são inteiramente free e open source. 

Ribamar FS ­ http://cursos.ribafs.org