Access Keys:
Skip to content (Access Key - 0)
 
iReport, Maven, Hibernate e HSQLDB na Pratica

Ola amigos do Sou Java.

Caso de uso Editar PDF:

Prévia descrição do UC:

 Dado um documento previamente analisado pelo usuário, paginado e conferido, o sistema deverá fazer uma pesquisa no banco de dados a fim de recuperar a entidade Documento, em seguida o sistema deve ser capaz de modificar o array de bytes do tipo BLOB, retirando ou colocando paginas de outro Documento neste array a fim de gerar um terceiro Documento que deve ser salvo em diretório especifico para posterior visualização.

Previa descrição dos componentes utilizados:

Banco de dados: HSQLDB, por ser opensource, fácil instalação e portabilidade incomparável, além de ser até 20x mais rápido que o derby.

Framework de persistência: Hibernate, facilidade no acesso aos dados e documentação extensa.

Framework de Relatórios: iReport para o controle de relatórios, paginação, criação, layout entre outras funções.

Maven: O Leitor pode entender mais sobre o maven acompanhando outros dois artigos do sou java: https://www.soujava.org.br/x/ZABi  e https://www.soujava.org.br/x/ZwBi
Neste artigo o leitor vai aprender:

Criar um projeto capaz de manipular um array de bytes [] com o iReport, configurar o Hibernate para acessar BLOB´s  e salvar em disco ou na base de dados. Recuperar o PDF da base de dados ou do disco, retirar paginas e juntar em um novo PDF. Recuperar o PDF da base ou do disco, e concatenar com outro PDF tb oriundo da base de dados ou do disco.

Como diz o Faustão: "quem sabe faz ao vivo"...o projeto segue para download no final do artigo. -.- 
Se o leitor tiver dificuldades no entendimento do artigo, por favor, entre em contato para que possamos juntos pensar em melhorias, aceito sugestões...  

O Primeiro passo é criar o projeto, então abra uma janela de comando no sistema operacional de sua preferência e digite os comandos conforme LOG abaixo:

C:\Java\workspace\ireport_na_pratica>mvn archetype:create -DarchetypeGroupId=org
.apache.maven.archetypes -DgroupId=br.org.soujava.ireport -DartifactId=ireport
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [archetype:create] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus
.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] [archetype:create]
[WARNING] This goal is deprecated. Please use mvn archetype:generate instead
[INFO] Defaulting package to group ID: br.org.soujava.ireport
[INFO] artifact org.apache.maven.archetypes:maven-archetype-quickstart: checking
 for updates from central
[INFO] -------------------------------------------------------------------------
---
[INFO] Using following parameters for creating OldArchetype: maven-archetype-qui
ckstart:RELEASE
[INFO] -------------------------------------------------------------------------
---
[INFO] Parameter: groupId, Value: br.org.soujava.ireport
[INFO] Parameter: packageName, Value: br.org.soujava.ireport
[INFO] Parameter: package, Value: br.org.soujava.ireport
[INFO] Parameter: artifactId, Value: ireport
[INFO] Parameter: basedir, Value: C:\Java\workspace\ireport_na_pratica
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] ********************* End of debug info from resources from generated POM
 ***********************
[INFO] OldArchetype created in dir: C:\Java\workspace\ireport_na_pratica\ireport
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5 seconds
[INFO] Finished at: Mon Apr 27 22:19:10 BRT 2009
[INFO] Final Memory: 7M/14M
[INFO] ------------------------------------------------------------------------
C:\Java\workspace\ireport_na_pratica>

Adicione as seguintes dependências no arquivo de configurações do Maven: pom.xml:

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.3.0.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.0.0.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>3.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.4.sp1</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.2</version>
</dependency>
</dependencies>

Execute o eclipse:eclipse no projeto para efetuar o download das dependencias e configurar o projeto para ser aberto no eclipse.

C:\Java\workspace\ireport_na_pratica\ireport>mvn eclipse:eclipse
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'eclipse'.
[INFO] ------------------------------------------------------------------------
[INFO] Building ireport
[INFO]    task-segment: [eclipse:eclipse]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing eclipse:eclipse
[INFO] No goals needed for project - skipping
[INFO] [eclipse:eclipse]
[INFO] Using as WTP server : null
[INFO] Adding default classpath contaigner: org.eclipse.jdt.launching.JRE_CONTAI
NER
(...)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Mon Apr 27 22:34:56 BRT 2009
[INFO] Final Memory: 6M/11M
[INFO] ------------------------------------------------------------------------

Agora importe o projeto no eclipse e em seguida crie uma classe chamada Documento, no pacote br.org.soujava.ireport, esta classe vai ser responsável por representar nossa entidade que contem o PDF.

//imports omitidos
@Entity @Table(name = "DOCUMENTO")
public class Documento {
@Id @GeneratedValue
@Column(name="ID")
private Long id; 
@Column(name="NOME")
private String nome; 
@Lob
private byte [] pdf;
//getters setters e construtores omitidos
}






Em seguida crie o arquivo de configurações hibernate-cfg conforme descrito abaixo:

(...)\ireport_na_pratica>cd ireport\src\main
(...)\ireport\src\main>mkdir resources
(...)\ireport\src\main>cd resources
(...)\ireport\src\main\resources>echo > hibernate.cfg.xml

Adicione ao arquivo as seguintes configurações:

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="show_sql">true</property>  
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">create-drop</property>
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>    
<property name="connection.url">jdbc:hsqldb:hsql://localhost:59999/ireport</property>         
<property name="connection.username">sa</property>
<!-- configuracoes para mapeamento -->
<mapping class="br.org.soujava.ireport.Documento"/>          
</session-factory>
</hibernate-configuration>






Agora crie a classe que vai nos auxiliar a obter uma conexão com o Hibernate, está classe deve se chamar HibernateUtil:

public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
try {       
AnnotationConfiguration antcfg = new AnnotationConfiguration();
antcfg.configure();
sessionFactory = antcfg.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}

Agora vamos ao que interessa no artigo que é as capacidades de fazer split, load e concat que vamos apresentar:

Primeiro vamos apresentar o método de Concat.

Este método navega por uma List<InputStream> dos pdfs carregados em memória, navega por esta lista, configura um layout padrão para as paginas e adiciona todas as paginas ao novo documento:

public static void concatPDFs(List<InputStream> streamOfPDFFiles,
OutputStream outputStream, boolean paginate) {
(...)
Iterator<InputStream> iteratorPDFs = pdfs.iterator();
while (iteratorPDFs.hasNext()) {
InputStream pdf = iteratorPDFs.next();
PdfReader pdfReader = new PdfReader(pdf);
readers.add(pdfReader);
totalPages += pdfReader.getNumberOfPages();
}
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfContentByte cb = writer.getDirectContent();
PdfImportedPage page;
int currentPageNumber = 0;
int pageOfCurrentReaderPDF = 0;
Iterator<PdfReader> iteratorPDFReader = readers.iterator();
while (iteratorPDFReader.hasNext()) {
PdfReader pdfReader = iteratorPDFReader.next();
while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
document.newPage();
pageOfCurrentReaderPDF++;
currentPageNumber++;
page = writer.getImportedPage(pdfReader,
pageOfCurrentReaderPDF);
cb.addTemplate(page, 0, 0);
if (paginate) {
cb.beginText();
cb.setFontAndSize(bf, 9);
cb.showTextAligned(PdfContentByte.ALIGN_CENTER, ""
+ currentPageNumber + " of " + totalPages, 520,
5, 0);
cb.endText();
}
}
pageOfCurrentReaderPDF = 0;
}
(...)
}







Este segundo método é responsável por dividir o pdf, e criar um novo com as paginas que são passadas por parâmetro de array de ints

public static void splitPDF(String file, OutputStream outputStream,
int[] paginas) {
Document document = null;
try {
PdfReader reader = new PdfReader(file);
document = new Document(reader.getPageSizeWithRotation(2));
PdfCopy writer = new PdfCopy(document, outputStream);
document.open();
for (int i = 0; i < paginas.length; i++) {
PdfImportedPage page = writer.getImportedPage(reader,
paginas[i]);
writer.addPage(page);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (document.isOpen()) {
document.close();
}
}
}

Este ultimo método é responsável por carregar um pdf em formato iReport para posterior manipulação:

public static Document loadPdfFromByte(byte[] pdf) {
Document document = null;
try {
PdfReader reader = new PdfReader(pdf);
document = new Document(reader.getPageSizeWithRotation(2));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (document.isOpen()) {
document.close();
}
}
return document;
}






Vamos testar tudo e ver se funciona ?

Crie a classe ConcatPDFTest.java

Nesta classe vamos fazer o processo de duas maneiras, carregando o PDF do disco, e carregando o PDF da base de dados...não vou explicar muito pois o código se explica sozinho...basta ler entender...acompanhe o código abaixo:

public class ConcatPDFTest extends TestCase {

public void testConcatFromDisk() {
try {
List<InputStream> pdfs = new ArrayList<InputStream>();
pdfs.add(new FileInputStream("C:\\pdf\\scwcd_notes.pdf"));
pdfs.add(new FileInputStream("C:\\pdf\\SCWCD_IBM_Success_Tutorial.pdf"));
OutputStream outputStream = new FileOutputStream("c:\\pdf\\scwcd_notes_SCWCD_IBM_Success_Tutorial.pdf");
IReportUtils.concatPDFs(pdfs, outputStream, true);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
} 
 
public void testConcatFromDB() {
try {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();   
File file = new File("C:\\pdf\\scwcd_notes.pdf");
byte [] pdf = null;
try {
FileInputStream fin = new FileInputStream(file);
pdf = new byte[(int) file.length()];
fin.read(pdf);  
} catch (Exception e) {
e.printStackTrace();
}  
Documento documento = new Documento(null,"SCWCD Notes",pdf);
session.save(documento);   
file = new File("C:\\pdf\\SCWCD_IBM_Success_Tutorial.pdf");  
try {
FileInputStream fin = new FileInputStream(file);
pdf = new byte[(int) file.length()];
fin.read(pdf);  
} catch (Exception e) {
e.printStackTrace();
}  
documento = new Documento(null,"SCWCD - IBM Success Tutorial",pdf); 
session.save(documento);   
List<Documento> documentos = session.createQuery("from Documento").list();
ByteArrayInputStream scwcd_notes = new ByteArrayInputStream(documentos.get(0).getPdf());
ByteArrayInputStream SCWCD_IBM_Success_Tutorial = new ByteArrayInputStream(documentos.get(1).getPdf());
List<InputStream> pdfs = new ArrayList<InputStream>();
pdfs.add(scwcd_notes);
pdfs.add(SCWCD_IBM_Success_Tutorial);
OutputStream outputStream = new FileOutputStream("c:\\pdf\\scwcd_notes_SCWCD_IBM_Success_Tutorial_FromDB.pdf");
IReportUtils.concatPDFs(pdfs, outputStream, true);  
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}






Agora crie a classe SplitPDFTest.java
Nesta classe vamos fazer o split de um pdf de duas maneiras, do disco e da base de dados...Acompanhe o código abaixo:

public class SplitPDFTest extends TestCase {
public void testSplitFromDisk() {
// RECUPERA DETERMINADAS PAGINAS E INSERE EM NOVO ARQUIVO
try {
String file = "c:\\pdf\\scwcd_notes.pdf";
OutputStream outputStream = new FileOutputStream("c:\\pdf\\scwcd_notes_SplitFromDisk.pdf");
int[] paginas = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
IReportUtils.splitPDF(file, outputStream, paginas);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void testSplitFromDB(){ 
// RECUPERA DETERMINADAS PAGINAS E INSERE EM NOVO ARQUIVO USANDO O HIBERNATE
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();   
File file = new File("C:\\pdf\\scwcd_notes.pdf");
byte [] pdf = null;
try {
FileInputStream fin = new FileInputStream(file);
pdf = new byte[(int) file.length()];
fin.read(pdf);  
} catch (Exception e) {
e.printStackTrace();
}  
Documento documento = new Documento(null,"SCWCD Notes",pdf);
session.save(documento);     
try {   
List<Documento> documentos = session.createQuery("from Documento").list();   
ByteArrayInputStream scwcd_notes = new ByteArrayInputStream(documentos.get(0).getPdf());   
PdfReader reader = new PdfReader(scwcd_notes);
OutputStream outputStream = new FileOutputStream("c:\\pdf\\scwcd_notes_SplitFromDB.pdf");
int[] paginas = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
IReportUtils.splitPDF(reader, outputStream, paginas);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}  
}
}








Execute as classes de teste no ambiente do eclipse e verifique os PDF que devem ser criados em (C:\pdf).

O Projeto completo pode ser baixado no link abaixo:

https://www.soujava.org.br/download/attachments/7208966/ireport_na_pratica.rar

Agradecimentos:

Todos que leram até aqui, todos que sempre me apoiaram e confiaram em mim e todos aqueles que contaram alguma vez com o meu apoio ou participou comigo de um projeto...eu espero tenha sido útil.

Autor:

Thomas Rafael Modeneis Sênior JEE Sun Certified Programmer for Java Platform, SE 5.0 - 310-055. at Elosoft S.A. thomas.modeneis at soujava dot org dot br

Equipe Sou Java, Fortalecendo a comunidade de usuários de Java do Brasil.

Adaptavist Theme Builder (3.1.4) Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.4 Build:#809 Jun 12, 2007)
Free theme builder license