Page Numbering Problems with iText

Asked

Viewed 985 times

0

Good afternoon, everyone.

I need to create reports with iText. Everything was going great until I needed to number these reports. I found a reply in someone else’s post on GUJ, but it didn’t work out so well.

Based on this tutorial (appropriate to my context) I managed to number only the last page of each PDF. Could someone give me a light how to number them all? Even better if it’s in the template "Page 1 of X".

Follow the full Class to assist:

public class Relatorio extends PdfPageEventHelper {

    private Font titulos = new Font(Font.FontFamily.HELVETICA, 20, Font.BOLD, new BaseColor(73, 146, 255));
    private Font subtitulo = new Font(Font.FontFamily.HELVETICA, 15, Font.BOLD, new BaseColor(73, 146, 255));
    private Font labels = new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD);
    private Font content = new Font(Font.FontFamily.HELVETICA, 10, Font.NORMAL);
    private List lista;
    private String filepath;

    public void onEndPage(PdfWriter w, Document d) {
        PdfContentByte cb = w.getDirectContent();
        cb.saveState();
        try {
            String txt = "Página "+w.getPageNumber();
            BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);

            float txtBase = d.top();
            float txtSize = bf.getWidthPoint(txt, 8);
            float adj = bf.getWidthPoint("0", 80);

            cb.beginText();
            cb.setFontAndSize(bf, 8);

            cb.setTextMatrix(d.right() - txtSize - adj, txtBase);
            cb.showText(txt);

            cb.endText();
        } catch (DocumentException | IOException e) { 
            e.printStackTrace();
        }  
        cb.restoreState();
    }

    private void prepararPDF(String nome, int opcao) {
        Document doc = null;
        FileOutputStream fos = null;
        String username = new com.sun.security.auth.module.NTSystem().getName().toString(); // Nome do usuario logado
        String fileName = null;
        filepath = "C:\\Users\\" + username + "\\Desktop\\Relatórios Hydros\\" + nome + "\\";

        try {
            File diretorio = new File(filepath);
            if (!diretorio.exists()) {
                diretorio.mkdirs();
            }

            fileName = "TEMP_" + new SimpleDateFormat("yyyy_MM_dd").format(new Date()).toString() + ".pdf";
            doc = new Document(PageSize.A4, 20, 20, 40, 40);
            fos = new FileOutputStream(filepath + fileName);
            PdfWriter w = PdfWriter.getInstance(doc, fos);

            doc.open();

            switch (opcao) {
                case 1: relatorioReservatorios(doc); break;
                case 2: relatorioBombas(doc); break;
                case 3: relatorioPlacas(doc); break;
                case 4: relatorioPortas(doc); break;
                case 5: relatorioBombasXReservatorios(doc); break;
            } 

            onEndPage(w, doc);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (doc != null)
                doc.close();

            if (fos != null) {
                try {
                    fos.close();
                    adicionarMarcaDagua(filepath, fileName);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void adicionarMarcaDagua(String path, String name) {
        try {
            String filepath = path + name;
            String newfilepath = path + name.substring(5);

            PdfReader pdfr = new PdfReader(filepath);
            int paginas = pdfr.getNumberOfPages(); 

            PdfStamper stamp = new PdfStamper(pdfr, new FileOutputStream(newfilepath));

            int i = 0;
            Image watermark = Image.getInstance("C:\\Users\\Hugo\\Dropbox\\Programação\\Java\\Projetos\\Eduardo\\Hidros\\Workspace\\Hidros\\WebContent\\resources\\img\\watermark.png");

            watermark.setAbsolutePosition(50, 375);
            watermark.scaleAbsolute(500, 110);

            PdfContentByte pdfcb;
            while (i < paginas) {
                i++;
                pdfcb = stamp.getUnderContent(i);
                pdfcb.addImage(watermark);   
            }
            stamp.close();
            pdfr.close();

            excluirArquivo(filepath);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    private void excluirArquivo(String path) {
        File f = new File(path);
        if (f.delete())
            System.out.println("Excluiu");
        else
            System.out.println("Não excluiu");
    }

    private void relatorioReservatorios(Document doc) throws DocumentException {
        Paragraph p = new Paragraph("RELATÓRIO DOS RESERVATÓRIOS - " + new SimpleDateFormat("dd/MM/yyyy").format(new Date()) + "\n", titulos);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        p = new Paragraph("Quantidade: " + lista.size() + " unidades.", subtitulo);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        doc.add(new Paragraph(" "));

        PdfPTable table = new PdfPTable(4);
        PdfPCell cell;

        cell = new PdfPCell(new Phrase("NOME", labels));
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("CAPACIDADE (Lts)", labels));
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("TIPO", labels));
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("OBSERVAÇÃO", labels));
        table.addCell(cell);

        Reservatorio r;
        for (int i = 0; i < lista.size(); i++) { 
            r = (Reservatorio) lista.get(i); 

            // Nome do reservatório 
            cell = new PdfPCell(new Phrase(r.getNomeReservatorio(), content));
            table.addCell(cell);

            // Capacidade do reservatório
            cell = new PdfPCell(new Phrase(String.valueOf(r.getCapacidadeReservatorio()), content));
            table.addCell(cell);

            // Tipo do reservatório
            cell = new PdfPCell(new Phrase(r.getTipoReservatorio(), content));
            table.addCell(cell);

            // Observação do reservatório 
            cell = new PdfPCell(new Phrase(r.getObsReservatorio(), content));
            table.addCell(cell); 
        }

        table.setWidths(new int[] { 80, 80, 80, 80 }); // Largura das colunas
        doc.add(table);
    }

    private void relatorioBombas(Document doc) throws DocumentException {
        Paragraph p = new Paragraph("RELATÓRIO DAS BOMBAS - " + new SimpleDateFormat("dd/MM/yyyy").format(new Date()) + "\n", titulos);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        p = new Paragraph("Quantidade: " + lista.size() + " unidades.", subtitulo);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        doc.add(new Paragraph(" "));

        PdfPTable table = new PdfPTable(4);
        PdfPCell cell;

        cell = new PdfPCell(new Phrase("NOME", labels));
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("VOLTAGEM (V)", labels));
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("POTÊNCIA (W)", labels));
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("OBSERVAÇÃO", labels));
        table.addCell(cell);

        Bomba b;
        for (int i = 0; i < lista.size(); i++) {  
            b = (Bomba) lista.get(i); 

            // Nome da Bomba 
            cell = new PdfPCell(new Phrase(b.getNomeBomba(), content));
            table.addCell(cell);

            // Voltagem da Bomba  
            cell = new PdfPCell(new Phrase(String.valueOf(b.getVoltagemBomba()), content));
            table.addCell(cell);

            // Potência da Bomba 
            cell = new PdfPCell(new Phrase(String.valueOf(b.getPotenciaBomba()), content));
            table.addCell(cell);

            // Observação da Bomba
            cell = new PdfPCell(new Phrase(b.getObsBomba(), content));
            table.addCell(cell); 
        }

        table.setWidths(new int[] { 80, 80, 80, 80 }); // Largura das colunas
        doc.add(table);
    }

    private void relatorioPlacas(Document doc) throws DocumentException {
        Paragraph p = new Paragraph("RELATÓRIO DAS PLACAS - " + new SimpleDateFormat("dd/MM/yyyy").format(new Date()) + "\n", titulos);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        p = new Paragraph("Quantidade: " + lista.size() + " unidades.", subtitulo);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        doc.add(new Paragraph(" "));

        PdfPTable table = new PdfPTable(2);
        PdfPCell cell;

        cell = new PdfPCell(new Phrase("NOME", labels));
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("IP", labels));
        table.addCell(cell);

        Placa pl;
        Anchor anchor;
        for (int i = 0; i < lista.size(); i++) {  
            pl = (Placa) lista.get(i); 

            // Nome da Placa 
            cell = new PdfPCell(new Phrase(pl.getNomePlaca(), content));
            table.addCell(cell);

            anchor = new Anchor(String.valueOf(pl.getIpPlaca()));
            anchor.setReference("http://"+pl.getIpPlaca());

            // IP da Placa 
            cell = new PdfPCell(anchor);
            table.addCell(cell);
        }

        table.setWidths(new int[] { 80, 80 }); // Largura das colunas
        doc.add(table);
    }

    private void relatorioPortas(Document doc) throws DocumentException {
        Paragraph p = new Paragraph("RELATÓRIO DAS PORTAS - " + new SimpleDateFormat("dd/MM/yyyy").format(new Date()) + "\n", titulos);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        p = new Paragraph("Quantidade: " + lista.size() + " unidades.", subtitulo);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        Porta po;
        Placa pl;
        Bomba b;
        Reservatorio r;

        for (int i = 0; i < lista.size(); i++) {
            PdfPTable table = new PdfPTable(2);
            PdfPCell cell;

            po = (Porta) lista.get(i);
            pl = po.getPlaca();
            b = po.getBomba();
            r = po.getReservatorio();

            // Pular linha
            doc.add(new Paragraph("\n"));

            // Nome da Placa
            cell = new PdfPCell(new Phrase("NOME DA PLACA", labels));
            table.addCell(cell);

            cell = new PdfPCell(new Phrase(pl.getNomePlaca(), content));
            table.addCell(cell);

            // IP da Placa
            cell = new PdfPCell(new Phrase("IP DA PLACA", labels));
            table.addCell(cell);

            cell = new PdfPCell(new Phrase(String.valueOf(pl.getIpPlaca()),
                    content));
            table.addCell(cell);

            // Número da Porta
            cell = new PdfPCell(new Phrase("NÚMERO DA PORTA", labels));
            table.addCell(cell);

            cell = new PdfPCell(new Phrase(String.valueOf(po.getNumeroPorta()),
                    content));
            table.addCell(cell);

            // Número da Porta
            cell = new PdfPCell(new Phrase("TIPO DA PORTA", labels));
            table.addCell(cell);

            cell = new PdfPCell(new Phrase(po.getTipoPorta().getNomeTipoPorta(), content));
            table.addCell(cell);

            // Nome da Bomba
            cell = new PdfPCell(new Phrase("NOME DA BOMBA A QUE ESTÁ VINCULADA", labels));
            table.addCell(cell);

            cell = new PdfPCell(new Phrase(b.getNomeBomba(), content));
            table.addCell(cell);

            // Nome da Bomba
            cell = new PdfPCell(new Phrase("NOME DO RESERVATÓRIO A QUE ESTÁ VINCULADA", labels));
            table.addCell(cell);

            cell = new PdfPCell(new Phrase(r.getNomeReservatorio(), content));
            table.addCell(cell);

            table.setWidths(new int[] { 250, 170 }); // Largura das colunas
            doc.add(table);
        }
    }

    private void relatorioBombasXReservatorios(Document doc) throws DocumentException {
        Paragraph p = new Paragraph("RELATÓRIO DE\nBOMBAS X RESERVATÓRIOS - " + new SimpleDateFormat("dd/MM/yyyy").format(new Date()) + "\n", titulos);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        p = new Paragraph("Quantidade: " + lista.size() + " unidades.", subtitulo);
        p.setAlignment(Element.ALIGN_CENTER);
        doc.add(p);

        doc.add(new Paragraph(" "));

        Bomba_Reservatorio br;
        Bomba b;
        Reservatorio r;

        PdfPTable table = new PdfPTable(2);
        PdfPCell cell;

        cell = new PdfPCell(new Phrase("NOME DA BOMBA", labels));
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("NOME DO RESERVATÓRIO", labels));
        table.addCell(cell);

        for (int i = 0; i < lista.size(); i++) { 
            br = (Bomba_Reservatorio) lista.get(i); 
            b = br.getBomba();
            r = br.getReservatorio();

            // Nome da Bomba 
            cell = new PdfPCell(new Phrase(b.getNomeBomba(), content));
            table.addCell(cell);

            // Nome da Bomba 
            cell = new PdfPCell(new Phrase(r.getNomeReservatorio(), content));
            table.addCell(cell); 
        }

        table.setWidths(new int[] { 250, 170 }); // Largura das colunas
        doc.add(table);
    }

    public void gerarRelatorio(int op, List lista) throws IOException {
        this.lista = lista;

        switch (op) {
            case 1: prepararPDF("Reservatórios", op); break;
            case 2: prepararPDF("Bombas", op); break;
            case 3: prepararPDF("Placas", op); break;
            case 4: prepararPDF("Portas", op); break;
            case 5: prepararPDF("Bombas X Reservatórios", op); break;
        } 

        Runtime.getRuntime().exec("explorer " + filepath); 
    } 
}

From now on, thank you!

1 answer

1


Your problem is that you are misusing the class PdfPageEventHelper. In the stretch

PdfWriter w = PdfWriter.getInstance(doc, fos);

doc.open();

switch (opcao) {
    case 1: relatorioReservatorios(doc); break;
    case 2: relatorioBombas(doc); break;
    case 3: relatorioPlacas(doc); break;
    case 4: relatorioPortas(doc); break;
    case 5: relatorioBombasXReservatorios(doc); break;
} 

onEndPage(w, doc);

you are calling the method onEndPage(w, doc) after generating the report by switch.That is, it will add the content of this method only on the current page of the document, in this case the last.
This method as well as the method onStartPage, should not be called separately, as they are methods that are automatically called by the events of endPage and startPage. What you should do is change this section to:

PdfWriter w = PdfWriter.getInstance(doc, fos);

w.setPageEvent( this );

doc.open();

switch (opcao) {
    case 1: relatorioReservatorios(doc); break;
    case 2: relatorioBombas(doc); break;
    case 3: relatorioPlacas(doc); break;
    case 4: relatorioPortas(doc); break;
    case 5: relatorioBombasXReservatorios(doc); break;
} 

where this is the class that extends the PdfPageEventHelper. In your case, it’s the class itself Relatorio.
In this way, you will be assigning a "Istener" to the events of endPage and startPage of this document and warning iText that, at the end of a page, the method onEndPage(w, doc) should be called.

It is possible to number in the "Page 1 of X" format, but the only way I can think of is to generate the document twice. The first time, it can be through a temporary file, so you can use iText even to check how many pages this document has. Thus, when generating for the second time, you will have the number of pages that this document will have.

Also consider separating the class PdfPageEventHelper and the rest of the report, the code becomes more organized and easy to understand.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.