es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo agregar encabezado y pie de página usando PdfStamper en iTextPDF cuando el servlet es sensible a la base de datos?

Tengo un servlet que crea un PDF directamente desde una base de datos MySQL. Todo funciona bien, pero ahora necesito agregar encabezados y pies de página en cada página de ese PDF generado dinámicamente. El encabezado debe mostrar ‘Página número_actual de número_total_de_páginas’ y el pie debe recuperar algunos datos de la base de datos MySQL y mostrarlos en formato de tabla. Realmente estoy atascado en este problema desde hace algunas semanas.

Estoy usando servlet 2.5 e itextpdf 5.5.4.

Aquí adjunto mi código:

El código anterior me da el siguiente error:

java.io.IOException: org.apache.catalina.connector.CoyoteOutputStream@10e18ba no encontrado como archivo o recurso.
en com.itextpdf.text.io.RandomAccessSourceFactory.createByReadingToMemory (RandomAccessSourceFactory.java: 263)
en com.itextpdf.text.io.RandomAccessSourceFactory.createBestSource (RandomAccessSourceFactory.java: 173)
en com.itextpdf.text.pdf.PdfReader. (PdfReader.java: 219)
en com.itextpdf.text.pdf.PdfReader. (PdfReader.java: 207)
en com.itextpdf.text.pdf.PdfReader. (PdfReader.java: 197)
en servlet_for_demand.formPart11PDF.doGet (formPart11PDF.java: 737)
en servlet_for_demand.formPart11PDF.doPost (formPart11PDF.java: 810)
en javax.servlet.http.HttpServlet.service (HttpServlet.java: 637)
en javax.servlet.http.HttpServlet.service (HttpServlet.java: 717)
en org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java: 290)
en org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java: 206)
en org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java: 233)
en org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java: 191)
en org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java: 127)
en org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java: 102)
en org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java: 109)
en org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java: 298)
en org.apache.coyote.http11.Http11Processor.process (Http11Processor.java: 859)
en org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process (Http11Protocol.java: 588)
en org.apache.tomcat.util.net.JIoEndpoint$Worker.run (JIoEndpoint.java: 489)
en java.lang.Thread.run (Fuente desconocida)

Aquí adjunto el código para crear la tabla de mi base de datos para que el desarrollador pueda encontrar una solución más fácil.

create database test;
use test;
create table dm_011(mmg_no varchar(40), i_des varchar(40), tg_dir varchar(40));
insert into dm_011 values (‘1′,’abcd’,’abcd1′);
insert into dm_011 values (‘2′,’efgh’,’efgh1′);

Por favor, ayúdame, no puedo encontrar ninguna solución.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para agregar un encabezado y un pie de página a cada página de un PDF generado dinámicamente creado por un servlet usando iTextPDF 5.5.4, puede seguir los siguientes pasos:

    1. Cree una clase PdfPageEventHelper que extienda la clase PdfPageEventHelper proporcionada por iTextPDF. Esta clase se utilizará para agregar el encabezado y el pie de página a cada página.
    class HeaderFooter extends PdfPageEventHelper {
        public void onEndPage(PdfWriter writer, Document document) {
            // Agregar encabezado
            PdfPTable header = new PdfPTable(1);
            header.getDefaultCell().setBackgroundColor(BaseColor.LIGHT_GRAY);
            header.addCell(new Phrase("Página " + writer.getPageNumber()));
            header.setTotalWidth(document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin());
            header.writeSelectedRows(0, -1, document.leftMargin(), document.top() + ((document.topMargin() + header.getTotalHeight()) / 2), writer.getDirectContent());
    
            // Agregar pie de página
            PdfPTable footer = new PdfPTable(1);
            PdfPCell cell = new PdfPCell(new Phrase("Datos de la base de datos"));
            cell.setBorder(0);
            footer.addCell(cell);
            footer.setTotalWidth(document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin());
            footer.writeSelectedRows(0, -1, document.leftMargin(), document.bottom() + ((document.bottomMargin() + footer.getTotalHeight()) / 2), writer.getDirectContent());
        }
    }
    
    1. En su método doGet, cree una instancia de la clase HeaderFooter anterior y pásela al PdfWriter.
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletOutputStream os = response.getOutputStream();
        response.setContentType("application/pdf");
        Document doc = new Document(PageSize.A4, 65, 50, 70, 100);
        PdfWriter writer = PdfWriter.getInstance(doc, os);
        HeaderFooter event = new HeaderFooter();
        writer.setPageEvent(event);
    
        // Resto de su código
    }
    

    Tenga en cuenta que hemos cambiado la instanciación de PdfWriter para incluir el documento y el flujo de salida, y también especificamos los márgenes del documento al crear la instancia de Document.

    1. Para recuperar datos de la base de datos MySQL, puede usar las clases PreparedStatement y ResultSet proporcionadas por JDBC. Por ejemplo, para recuperar los datos para el pie de página del PDF, puede modificar su código de la siguiente manera:
    Connection conn = null; 
    PreparedStatement pst = null;
    String sql = null;
    float[] columnWidths = {70f, 30f};
    PdfPTable table = new PdfPTable(columnWidths);
    table.setWidthPercentage(100f);
    try {
        DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        conn = DriverManager.getConnection(dbURL, dbUser, dbPass);
        sql = "select some_column from some_table where some_condition=?";
        pst = conn.prepareStatement(sql);
        pst.setString(1, some_value);
        ResultSet rs = pst.executeQuery();
        while(rs.next()) {
            PdfPCell cell = new PdfPCell(new Phrase(rs.getString("some_column")));
            cell.setBorder(0);
            table.addCell(cell);
        }
        rs.close();                                                                
        pst.close();                                                              
        pst = null;                                                               
        conn.close();                                                              
        conn = null;
    } catch (SQLException e) {
        // Manejar excepción
    }
    

    Aquí, "some_column" es el nombre de una columna en su tabla de base de datos, y some_value es un valor para el que desea recuperar los datos.

    1. Finalmente, agregue la instancia de table al pie de página de cada página en el método onEndPage de la clase HeaderFooter creada anteriormente.
    PdfPTable footer = new PdfPTable(1);
    PdfPCell cell = new PdfPCell(new Phrase("Datos de la base de datos"));
    cell.setBorder(0);
    footer.addCell(cell);
    footer.addCell(table);
    footer.setTotalWidth(document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin());
    footer.writeSelectedRows(0, -1, document.leftMargin(), document.bottom() + ((document.bottomMargin() + footer.getTotalHeight()) / 2), writer.getDirectContent());
    

    Tenga en cuenta que hemos agregado la instancia de table como una nueva celda a la tabla footer creada anteriormente. Además, hemos incluido la tabla footer en el método writeSelectedRows para colocarla correctamente en la página del PDF.

    Con estas modificaciones, su servlet ahora debería poder generar un PDF con encabezados y pies de página en cada página, y recuperar datos de la base de datos MySQL para mostrar en el pie de página.

Comments are closed.