Cómo crear informes PDF en React

En este artículo, crearemos un botón que genera un documento PDF (como ve arriba) basado en datos de una llamada API.

Hace un par de días, desarrollé una aplicación CRM de pila completa para administrar la comunicación entre clientes y agentes de soporte.

Necesitaba una forma para que los agentes generaran un resumen de los tickets cerrados como un archivo PDF. Después de buscar en Internet una forma FÁCIL de hacer esto, me atrevo a decir que este artículo le mostrará la forma más fácil de hacerlo.

Entremos en ello, ¿de acuerdo?

Paquetes de instalación

Primero, instalemos los paquetes que necesitamos.

npm i jspdf jspdf-autotable 

Definir una función para generar los PDF

A continuación, definamos una función que podamos llamar en cualquier lugar para generar un PDF para nosotros. Agregué muchos comentarios para ayudarlo a comprender lo que sucede con cada línea.

// services/reportGenerator.js import jsPDF from "jspdf"; import "jspdf-autotable"; // Date Fns is used to format the dates we receive // from our API call import { format } from "date-fns"; // define a generatePDF function that accepts a tickets argument const generatePDF = tickets => { // initialize jsPDF const doc = new jsPDF(); // define the columns we want and their titles const tableColumn = ["Id", "Title", "Issue", "Status", "Closed on"]; // define an empty array of rows const tableRows = []; // for each ticket pass all its data into an array tickets.forEach(ticket => { const ticketData = [ ticket.id, ticket.title, ticket.request, ticket.status, // called date-fns to format the date on the ticket format(new Date(ticket.updated_at), "yyyy-MM-dd") ]; // push each tickcet's info into a row tableRows.push(ticketData); }); // startY is basically margin-top doc.autoTable(tableColumn, tableRows, { startY: 20 }); const date = Date().split(" "); // we use a date string to generate our filename. const dateStr = date[0] + date[1] + date[2] + date[3] + date[4]; // ticket title. and margin-top + margin-left doc.text("Closed tickets within the last one month.", 14, 15); // we define the name of our PDF file. doc.save(`report_${dateStr}.pdf`); }; export default generatePDF; 

Crea un componente para guardar los tickets a renderizar

Ahora, creemos un Componente simple que obtenga y guarde el ticket en el estado.

import React, { useEffect, useState } from "react"; import generatePDF from "../services/reportGenerator"; const Tickets = () => { const [tickets, setTickets] = useState([]); useEffect(() => { const getAllTickets = async () => { try { const response = await axios.get("//localhost:3000/tickets"); setTickets(response.data.tickets); } catch (err) { console.log("error"); } }; getAllTickets(); }, []); const reportTickets = tickets.filter(ticket => ticket.status === "completed"); return ( {user.user.role === "user" ? (   ) : (  generatePDF(reportTickets)} > Generate monthly report  )} ); }; export default Tickets; 

Algunos puntos sobre nuestro componente. Cuando nuestro componente se carga, hacemos una solicitud a // localhost: 3000 / tickets para buscar todos nuestros tickets. Luego los guardamos en el ticketsestado. Y finalmente, los pasamos como utilería para renderizar los tickets en el DOM.

También tenemos una reportTicketsvariable que filtra nuestros tickets para obtener solo los tickets que tienen el estado de completed.

Observe que también creamos el botón Generar informe mensual que llama a la generatePDF()función que definimos anteriormente al hacer clic.

Crea un componente para mostrar los tickets en una tabla.

A continuación, definamos nuestro que será responsable de mostrar nuestros tickets en una bonita mesa. Recuerde que acepta que los tickets se muestren como un accesorio del componente.

import React from "react"; import { Link } from "react-router-dom"; const TicketsComponent = ({ tickets }) => { // a function that assigns bootstrap styling classes based on // the status of the ticket const assignColorToTicketStatus = ticket => { if (ticket.status === "completed") { return "p-3 mb-2 bg-success text-white"; } else if (ticket.status === "in_progress") { return "p-3 mb-2 bg-warning text-dark"; } else if (ticket.status === "opened") { return "p-3 mb-2 bg-light text-dark"; } }; return ( {tickets.length === 0 ? ( "You currently have no tickets created" ) : ( 
    
       {tickets.map(ticket => ( 
       ))} 
     
# Title Issue Status
{ticket.id} {ticket.title} {ticket.request} {ticket.status} See comments
)} ); }; export default TicketsComponent;

Ahora, veamos cómo se ve nuestra aplicación actualmente. Tenemos 10 boletos en nuestro estado, pero mostraré 6 aquí para mayor comodidad.

Como puede ver, tenemos varios tickets en diferentes estados. También tenemos nuestro botón Generar informe mensual que, al hacer clic, exportará el archivo PDF.

Y eso es. Debería terminar con un archivo PDF con el nombre de archivo en el formulario report_dddmmyyyy descargado en su navegador.

Si este artículo te ayudó, saluda en Twitter.