Jasper Report vs. iText vs. JRTF

Arthur Magalhaes Fonseca
4 min readMay 25, 2016

--

Há algum tempo precisei de uma solução em meu trabalho para retornar relatórios RTF via serviço.

Dado a grande variedade de APIs e frameworks que fazem isso, optei por um que eu sempre ouvi falar, o Jasper Report.

O Jasper é bastante intuitivo e possui uma comunidade bem ativa. Fiz a configuração deste com o Maven muito rápido, utilizei um plugin no Eclipse e através de recursos como reports e subreports pude reaproveitar cabeçalhos e rodapés. Isso foi uma maravilha para mim, consegui gerar relatórios muito rápido, tendo apenas a inconveniência de ter que posicionar elemento por elemento. Bem… foi o que eu pensei…

O requisito do cliente era gerar um RTF e isso eu estava fazendo, mas recebi reclamações sobre excesso de “texto” de configuração no documento gerado.

A princípio não entendi o problema, o que me foi passado foi que o Jasper estava gerando alguns textos desses quando consumido por um serviço legado:

fFilled0lineColor0fLine0lineWidth0shapeType20lineColor0lineWidth12700fFlipV0fFilled0dyTextTop0dxTextLeft0dyTextBottom0dxTextRight0fLine0

Ao analisar com mais calma os relatórios gerados percebi que cada TextField e cada StaticText estava sendo gerado contido em uma caixa de texto:

Nesse momento, os posicionamentos X, Y inseridos no arquivo JRXML começaram a fazer sentido. Não eram adicionadas quebras de páginas ou ENTERs, cada elemento era posicionado por caixa de texto.

Para a maioria das pessoas, creio que esse não é um grande problema, mas no meu caso, um serviço legado não conseguia processar essa informação. Apesar de acreditar não haver forma de contornar isso, fui buscar se havia uma forma de eliminar essas caixas de texto.

Encontro o seguinte post, que basicamente dizia:

Unfortunately there’s no possibility to avoid RTF textboxes at the moment.Due to pixel-perfect output requirements, the RTF exporter in JR is based on textbox-layout.

Ciente que teria que encontrar outra solução, me deparei com o iText e o JRTF

Ambos resolveram meu problema de caixa de texto, seguem minhas impressões:

iText

A princípio o iText me passou a impressão de ser uma implementação muito mais engessada. Achei muito verbosa a forma de codificação, cheia de gets e sets. Fora isso, o tamanho utilizado em espaçamentos é em Points, precisei converter de Points para Centímetros para atender à demanda do cliente.

A princípio fiquei confuso quanto à última versão do iText no repositório Maven, o nome havia sido trocado para itextpdf, utilizei uma versão mais antiga da biblioteca, aparentemente o suporte a RTF foi removido.

A seguir seguem alguns exemplos que implementei:

  • Criação de documento e especificação de caminho a ser salvo.
Document document = new Document();
RtfWriter2.getInstance(document,
new FileOutputStream(“relatorio.rtf”));

document.open();
  • Cria uma imagem, seta uma escala de proporção e a alinha ao centro
Image image = Image.getInstance(“src/main/resources/logo.png”);
image.scalePercent(25);
image.setAlignment(Element.ALIGN_CENTER);
document.add(image);
  • Criação de parágrafo, e o problema que tive com o tamanho em Points
Paragraph p1 = new Paragraph(“Primeiro parágrafo”);
p1.setAlignment(Element.ALIGN_JUSTIFIED);
p1.setFont(new Font(Font.TIMES_ROMAN, 11, Font.BOLD));
p1.setIndentationLeft(new Double(3/0.0352778).floatValue());
p1.setSpacingBefore(11);

document.add(p1);
  • Criação de tabela
Table t = new Table(2);
t.addCell(new Cell(p2));
t.addCell(new Cell(p3));
t.setAlignment(Table.ALIGN_CENTER);
document.add(t);

Como deu para observar, a manipulação se dá em criar algo e adicionar a um Document em questão. Ao final, invoca-se o método close() do documento em questão para a geração do arquivo.

JRTF

O JRTF foi uma grande surpresa para mim, e o fato de me deparar com uma API que utiliza o Designer Pattern Fluent Interface já me chamou mais a atenção que o iText. Achei as coisas muito simples, apesar de o próprio projeto mencionar as deficiências e necessidades a serem levadas em consideração, bem como a seguinte frase:

If you are looking to a mature open source alternative take a look at iText RTF (http://sourceforge.net/projects/itextrtf/). Unfortunately the RTF support was removed from the official build and you have to search for the RTF version explicitly.

A princípio pensei que não haveria uma versão do projeto no repositório Maven, mas encontrei a versão 0.7

A possibilidade de escolher a unidade de medida a ser utilizada (CM, INCH, POINT e TWIPS) também foi uma grande vantagem que encontrei. A única coisa que encontrei dificuldade foi em alinhar uma tabela ao centro, bem como alinhar o texto de cada célula.

Encontrei inclusive um projeto homônimo de fork que dizia implementar mais coisas.

Vamos então ao exemplo de funcionamento de um código semelhante ao exemplificado acima:

rtf()
.header(
RtfHeader.font(RtfHeaderFont.ARIAL)
)
.section(
p(picture(ClassLoader.getSystemClassLoader()
.getResourceAsStream(“logo.png”))
.scale(40, 40).type(PictureType.AUTOMATIC)).alignCentered(),
p(fontSize(22, “Primeiro parágrafo”))
.alignJustified().indentFirstLine(3, CM),
row(
p(“coluna 1”).cellWidth(10, CM),
p(“coluna 2”).cellWidth(10, CM)
).bottomCellBorder().leftCellBorder().rightCellBorder()
.topCellBorder()
).out(new FileWriter(new File(“relatorio.rtf”)));

Conclusão

Apesar de ambos resolverem o meu problema de caixa de texto, para o cenário em questão, pendo minha escolha para JRTF por definições arquiteturais de implementação.

Mesmo as limitações que foram informadas não tiveram tanto impacto para mim.

Estou lendo o excelente livro Código Limpo do Robert C. Martin, vulgo Uncle Bob (a tradução para Tio Bob perde toda graça), e logo no início tem uma frase que me chamou muito a atenção quanto à definição de um código limpo:

Um código limpo é simples e direto. Ele é tão bem legível quanto uma prosa bem escrita. Ele jamais torna confuso o objetivo do desenvolvedor, em vez disso, ele está repleto de abstrações claras e linhas de controle objetivas. — BOOCH, Grandy

É basicamente isso que senti ao ler o código o código do JRTF… Como é interessante se deparar com um código simples de se ler…

--

--

No responses yet