Los PDFs (Portable Document Format) son el esquema por excelencia para compartir textos con formatos en un archivo, son fáciles de interpretar y no requieren un programa propietario como en el caso de los archivos de Microsoft Word. Los PDFs al ser un formato ya listo y sin posibilidad de modificarlos (aunque sí se pueden modificar con algunos programas específicos) como si fueran una imagen, es una excelente manera de compartir documentos y en las aplicaciones móviles y de escritorio y de ningún tipo en general pueden faltar, y en Flutter estamos de suerte ya que se pueden emplear muy fácilmente.
La gestión de archivos PDF es una necesidad común en aplicaciones modernas: reportes, facturas, contratos, manuales, comprobantes y más. En Flutter, este escenario se divide en dos grandes áreas:
- Visualización de PDFs (PDF Viewer)
- Generación dinámica de PDFs
¿Qué aprenderás en esta guía?
- Cómo visualizar PDFs en Flutter usando diferentes paquetes.
- Comparativa real basada en feedback de desarrolladores.
- Cómo generar PDFs dinámicos (facturas, reportes, listas).
- Cómo mostrar un “PDF Preview” interactivo.
- Cómo descargar, compartir o imprimir un PDF.
- Buenas prácticas, recomendaciones y problemas comunes.
- Código real probado con los paquetes pdf y printing.
⭐ Introducción: ¿Por qué PDF en Flutter?
Flutter ofrece una gran ventaja: la capacidad de trabajar con documentos en cualquier plataforma (Android, iOS, Web, Desktop). Esto permite crear apps empresariales, e-commerce, ERPs, puntos de venta o apps de gestión, donde el PDF es central.
Pero algo es cierto:
- No todos los paquetes PDF funcionan igual de bien.
- Y muchos desarrolladores no saben que algunos paquetes pueden volverse de pago en el futuro.
Flutter no incluye soporte nativo para leer o generar PDFs, pero sí cuenta con un ecosistema sólido gracias a paquetes de terceros.
Existen dos escenarios principales:
1️⃣ Visualización de PDFs
Mostrar archivos PDF locales, remotos o generados dentro de la app.
2️⃣ Generación de PDFs
Crear documentos PDF desde cero mediante código.
En esta guía cubrimos ambos.
Por eso este artículo recopila experiencias reales de desarrolladores, casos de uso y recomendaciones prácticas para que tomes decisiones informadas.
Parte 1 — Mejor visor PDF gratuito para Flutter (según la comunidad)
Una pregunta frecuente en la comunidad de Flutter es:
“¿Cuál es el mejor visor PDF gratis para Flutter?”
Un usuario experimentó problemas con flutter_pdfview (_pdfview) y descubrió que requería más pasos para mostrar un PDF desde assets. Luego probó pdfrx y funcionó “a la primera” con una sola línea de código.
La discusión revela varias cosas importantes.
- 1. flutter_pdfview (_pdfview)
✔ Ventajas - Muy popular en pub.dev
- Funciona bien en muchos dispositivos
- Comunidad activa
❌ Desventajas reportadas
- “file not found” al cargar PDF desde assets
- Requiere copiar el PDF a un directorio temporal antes de abrirlo
- Más código para un caso sencillo
Problemas de renderizado en modelos Android de gama baja
Algunos usuarios reportan cierres inesperados
Para mostrar un PDF desde assets, terminas escribiendo más de 20 líneas extra solo para copiar el archivo temporalmente.
Para muchos, esto es “demasiado trabajo para abrir un PDF”.
2. pdfrx (Elección recomendada por la comunidad)
✔ Ventajas
- Multi-plataforma (Android, iOS, Web, Desktop)
- Carga PDF desde assets con una sola línea
- Más rápido que _pdfview en la mayoría de dispositivos
- Misma autoría que pdf_render, librería con años de trayectoria
- Excelente experiencia inicial: funciona sin complicaciones
❌ Desventajas
- Menos descargas que _pdfview (porque es más nuevo)
- Todavía está creciendo su comunidad
- ⚠ Pregunta importante del usuario:
- “¿Puede volverse de pago en el futuro?”
- Respuesta de la comunidad:
- Técnicamente cualquier paquete gratuito podría cambiar sus reglas de uso
- Pero nada indica que pdfrx lo vaya a hacer
- La recomendación general fue: si te funciona bien, quédate con él
3. Syncfusion PDF Viewer
- ✔ Pro
- Es el más completo del mercado
- Muchas funciones empresariales
❌ Contras muy serios (explicados por un usuario experto)
- NO es open-source
- Licencia comercial
- Si tu empresa tiene más de 5 desarrolladores, debes pagar una licencia cara
- Esto también afecta a quienes usen tu código
Por eso, muchos desarrolladores recomiendan evitar Syncfusion si quieres mantener tu proyecto 100% libre.
4. Otros paquetes mencionados
- nutrient.io → muy avanzado, pero orientado a soluciones premium
- UPDF → recomendado como herramienta externa, no como paquete Flutter
Conclusión de la Parte 1
Mejor visor PDF en Flutter (2025): pdfrx
- Fácil
- Rápido
- Multi-plataforma
- Menos errores
- Ideal para Flutter Web + Mobile
Parte 2 — Generación dinámica de PDFs en Flutter (con pdf y printing)
En este artículo te mostraré todo lo que necesitas saber para manejar PDF en Flutter:
los mejores visores gratuitos, los paquetes más confiables, los riesgos reales del uso de librerías, y cómo generar PDFs profesionales utilizando pdf y printing.
Además, incluimos código completo, comparaciones, advertencias sobre licencias y una guía clara para elegir la mejor solución según tu proyecto.
1. Configuración Inicial
Antes de comenzar a desarrollar, debemos de configurar el plugin o pub en nuestro proyecto:
pubspec.yaml
dependencies:
flutter:
sdk: flutter
pdf:
printing:
http:- pdf: Esta biblioteca nos permite crear y editar PDFs en Flutter.
- printing: Nos permite previsualizar, compartir e imprimir los PDFs generados desde nuestra aplicación.
2. Creando un Modelo de Factura
Supongamos que deseas generar facturas para tus clientes, que es el enfoque más común para querer compartir y generar PDFs en Flutter. Primero, crea un modelo de datos para representar una factura. Puedes incluir información relevante como el nombre del cliente, los ítems de la factura y el total a pagar, este modelo puede ser cualquier cosa según tus necesidades como una publicación.
3. Diseñando la Interfaz
Diseña una interfaz de usuario donde los usuarios puedan ingresar los detalles de la factura. Utiliza widgets como TextFormField, ListView, y RaisedButton para capturar la información necesaria. Este paso es opcional ya que, puede que sean algunos datos estáticos o datos que provengan de alguna base de datos o similar así que, tampoco es importante para la creación del pdf y depende de tus necesidades o las del proyecto.
4. Generando el PDF
Este paso si es fundamental y se debe de generar el PDF, que es el factor importante en esta entrada así que, una vez que tengas los datos de la factura, vamos a generar el PDF con los paquetes anteriores, mediante la librería de pdf instalada antes, creamos un widgets especial que mediante un árbol de widgets permite generar el documento PDF; puedes utilizar cualquier tipo de widget visual de Flutter para esta tarea para generar textos, imágenes, tablas, etc:
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
// ...
final pdf = pw.Document();
pdf.addPage(
pw.Page(
build: (context) {
return pw.Center(
child: pw.Text('Factura para Cliente X'),
);
},
),
);5. Previsualización y Compartición
Con el PDF generado, es momento de emplear la biblioteca printing para previsualizar el PDF antes de guardarlo o enviarlo al cliente. Puedes mostrarlo en un PdfPreview o incluso enviarlo por correo electrónico directamente desde tu aplicación:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
final response = await http.get('http://example.com/sample.pdf');
final pdfData = response.bodyBytes;
await Printing.layoutPdf(onLayout: (PdfPageFormat format) async => pdfData);
},
child: Text('Show PDF'),
),
),
),
);
}
}Generar un PDF desde datos de una API
Paso 2 — Obtener los datos (API REST)
Future<List<Map<String, dynamic>>> fetchData() async {
try {
final response = await http.get(Uri.parse(
'http://192.168.1.100:8080/selectOrderItem?orderId=1',
));
if (response.statusCode == 200 || response.statusCode == 202) {
final List<dynamic> jsonData = json.decode(response.body);
return List<Map<String, dynamic>>.from(jsonData);
} else {
throw Exception('Failed to load data: ${response.statusCode}');
}
} catch (e) {
throw Exception('Failed to load data: $e');
}
}Paso 3 — Construir el PDF (estructura completa)
Aquí viene la parte más visual.
El PDF se construye como un árbol de widgets, igual que en Flutter, pero usando pw.:
- pw.Text()
- pw.Column()
- pw.Table()
- pw.Row()
- pw.Image()
Incluye:
encabezado con logo
tabla de proveedor
tabla de compra
tabla de detalles de productos
Tu código representa un documento profesional ideal para empresas.
Paso 4 — Previsualizar el PDF dentro de Flutter
void showPdfPreview(pw.Document pdf) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('PDF Preview'),
content: Container(
width: double.maxFinite,
height: 400,
child: PdfPreview(
build: (format) => pdf.save(),
allowPrinting: false,
allowSharing: true,
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('Close'),
),
],
),
);
}Esto funciona en:
- Flutter Web
- Android
- iOS
- Desktop
Paso 5 — Integrarlo en la UI
ElevatedButton(
onPressed: () async {
final pdf = await generatePdfReport(data);
showPdfPreview(pdf);
},
child: Text("Show Report"),
),️ Generar PDF otros ejemplos
Este bloque está basado en tu contenido original extendido y estructurado premium.
- Crearemos un PDF con:
- Encabezado + logo
- Datos principales (cliente, proveedor, fecha…)
- Tabla dinámica
Totales
Ejemplo completo:
Future<pw.Document> generatePdfReport(int index) async {
final pdf = pw.Document();
final netImage = await networkImage(
'https://i.postimg.cc/02xHkDLd/preview.jpg',
);
final selectedPurchase = purHomeList[index];
final detailList = await Rest.getData(
'getPurchaseDetails?poNo=${selectedPurchase['po_no']}',
);
pdf.addPage(
pw.Page(
build: (context) => pw.Container(
padding: const pw.EdgeInsets.all(12),
decoration: pw.BoxDecoration(
border: pw.Border.all(color: PdfColors.black),
),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
// Header
pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
children: [
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text("NAVINOMIX PVT LTD",
style: pw.TextStyle(
fontSize: 18,
fontWeight: pw.FontWeight.bold)),
pw.Text("Kings Landing 7609 Mckinley Ave"),
pw.Text("Los Angeles, California"),
pw.Text("Contact: +91-9663627343"),
pw.Text("info@navinprince.com"),
pw.Text("www.navinomix.com"),
],
),
pw.Image(netImage, width: 70, height: 100),
],
),
pw.SizedBox(height: 20),
// Purchase Information Table
pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Expanded(
child: infoTable(selectedPurchase),
),
pw.SizedBox(width: 10),
pw.Expanded(
child: infoRightTable(selectedPurchase),
),
],
),
pw.SizedBox(height: 20),
// Items Table
detailTable(detailList),
],
),
),
),
);
return pdf;
}(Funciones auxiliares "infoTable" y "detailTable" pueden modularizarse para clean code.)
Paso 3 — Mostrar un PDF Preview
Una joya del paquete printing:
void showPdfPreview(pw.Document pdf) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('PDF Preview'),
content: Container(
width: double.infinity,
height: 450,
child: PdfPreview(
build: (format) => pdf.save(),
allowPrinting: true,
allowSharing: true,
),
),
),
);
}Permite:
- Ver el PDF
- Hacer zoom
- Compartirlo
- Imprimirlo
▶️ Paso 4 — Integrarlo a la interfaz
ElevatedButton(
onPressed: () async {
final pdf = await generatePdfReport(0);
showPdfPreview(pdf);
},
child: Text("Generar & Mostrar PDF"),
)
Acepto recibir anuncios de interes sobre este Blog.
Descubre cómo trabajar con PDF en Flutter paso a paso: visualización, generación, vista previa, compartición y los mejores paquetes como pdfrx, pdf, printing y más. Aprende a abrir archivos PDF desde assets, red, almacenamiento local y a crear reportes profesionales, facturas y documentos dinámicos con ejemplos reales y código listo para usar. La guía definitiva de PDF en Flutter.