Repetir párrafos - Guía del bucle foreach
Los documentos suelen contener estructuras de contenido repetitivas, como listas de elementos, múltiples registros o secciones repetidas con un formato similar. PDF4meEl motor de plantillas proporciona potentes capacidades de iteración para generar dinámicamente múltiples párrafos y secciones a partir de colecciones de datos.
Comprender los bucles foreach
El foreach El bucle es el mecanismo principal para iterar a través de colecciones de datos y generar contenido repetido. Cada iteración procesa un elemento de la colección y genera la salida correspondiente.
Sintaxis básica de Foreach
<<foreach [item in collection]>>
Content with <<[item.property]>>
<</foreach>>
Componentes:
item- Variable que representa el elemento actual en la iteracióncollection- El array o colección de datos que se va a iterar- Bloque de contenido: el contenido de la plantilla se repite para cada elemento.
Párrafos repetidos
Genera varios párrafos iterando a través de una recopilación de datos y creando texto formateado para cada elemento.
Ejemplo: Calificaciones de la aplicación
Sintaxis de la plantilla:
<<foreach [app in applications]>><<[app.listAppName]>> in <<[app.listAppType]>> platform is a <<[app.category]>> app and has a <<[app.AppRating]>> rating.
<</foreach>>
Fuente de datos (JSON):
{
"surveyName": "Top-rated Apps",
"applications": [
{
"listAppName": "Instagram",
"listAppType": "iOS",
"category": "Social Media",
"AppRating": "4.9"
},
{
"listAppName": "Whatsapp",
"listAppType": "iOS",
"category": "Chat",
"AppRating": "4.8"
},
{
"listAppName": "Player UG",
"listAppType": "Android",
"category": "Gaming",
"AppRating": "4.75"
}
]
}
Salida generada:
Instagram in iOS platform is a Social Media app and has a 4.9 rating.
Whatsapp in iOS platform is a Chat app and has a 4.8 rating.
Player UG in Android platform is a Gaming app and has a 4.75 rating.
Gestión de colecciones vacías
Cuando una colección pueda estar vacía, utilice la Any() Método para comprobar si hay datos antes de iterar. Esto evita excepciones de valores nulos y permite mostrar contenido alternativo.
Verificación básica de nulidad
Plantilla con comprobación Any():
<<if [applications.Any()]>>
<<foreach [app in applications]>><<[app.listAppName]>> in <<[app.listAppType]>> platform is a <<[app.category]>> app and has a <<[app.AppRating]>> rating.
<</foreach>>
<<else>>No applications listed
<</if>>
Este enfoque:
- Comprueba si la colección contiene algún elemento.
- Recorre los elementos si están disponibles.
- Muestra un mensaje alternativo si la colección está vacía.
Bucles foreach anidados
Crea estructuras jerárquicas anidando bucles foreach. Esto resulta útil para mostrar relaciones padre-hijo o estructuras de datos multinivel.
Ejemplo: Departamento y empleados
Plantilla:
<<foreach [dept in departments]>>
Department: <<[dept.name]>>
<<foreach [emp in dept.employees]>>
- <<[emp.name]>> (<<[emp.position]>>)
<</foreach>>
<</foreach>>
Datos:
{
"departments": [
{
"name": "Engineering",
"employees": [
{ "name": "John Smith", "position": "Senior Developer" },
{ "name": "Jane Doe", "position": "Tech Lead" }
]
},
{
"name": "Marketing",
"employees": [
{ "name": "Mike Johnson", "position": "Marketing Manager" }
]
}
]
}
Secciones complejas repetitivas
Los bucles foreach pueden repetir secciones completas de contenido, incluyendo varios párrafos, formato y estructuras anidadas.
Repetición de varios párrafos
Plantilla:
<<foreach [product in products]>>
Product Name: <<[product.name]>>
Description: <<[product.description]>>
Price: $<<[product.price]>>
Available: <<[product.inStock]>>
<</foreach>>
Esta plantilla genera un bloque de descripción de producto completo para cada producto, manteniendo todo el formato y los saltos de párrafo.
Iteración condicional
Combine bucles foreach con sentencias condicionales para la generación selectiva de contenido.
Ejemplo: Visualización condicional
Plantilla:
<<foreach [employee in employees]>>
<<if [employee.age > 50]>>
Senior Employee: <<[employee.name]>> - Age: <<[employee.age]>>
<</if>>
<</foreach>>
Como alternativa, utilice métodos de enumeración:
Plantilla:
<<foreach [employee in employees.Where(e => e.age > 50)]>>
Senior Employee: <<[employee.name]>> - Age: <<[employee.age]>>
<</foreach>>
Formato dentro de bucles
Aplique formato a los campos dentro de los bucles foreach para obtener un estilo de salida uniforme.
Plantilla:
<<foreach [customer in customers]>>
Customer: <<[customer.name]:caps>>
Last Visit: <<[customer.lastVisit]:"MMMM dd, yyyy">>
Status: <<[customer.status]:upper>>
<</foreach>>
Variables de bucle e indexación
Acceda a la información de la posición del bucle utilizando variables implícitas (si su versión del motor de plantillas lo admite).
Variables comunes de bucle
- Índice del artículo actual (basado en 0 o en 1, según la implementación)
- Número de iteraciones del bucle
- Indicadores de primer/último artículo
Ejemplo de uso (si es compatible):
<<foreach [item in items]>>
<<[$index + 1]>>. <<[item.name]>>
<</foreach>>
Consideraciones de rendimiento
Mejores prácticas para bucles
- Limitar el tamaño de la colección - Filtrar colecciones grandes antes del procesamiento de plantillas
- Evite la anidación profunda - Limita los bucles anidados a 2-3 niveles para un mejor rendimiento.
- Preprocesar datos - Realizar cálculos complejos antes de pasar los datos a las plantillas.
- Utilice consultas eficientes - Filtrar y ordenar los datos a nivel de la fuente de datos.
Ejemplo: Datos prefiltrados
En lugar de:
<<foreach [emp in employees.Where(e => e.age > 30).OrderBy(e => e.name)]>>
Prefiltra en tu aplicación y pasa los datos filtrados:
<<foreach [emp in filteredEmployees]>>
Patrones comunes
Patrón 1: Lista numerada
<<foreach [item in items]>>
<<[$index]>>. <<[item.title]>>
<</foreach>>
Patrón 2: Contenido agrupado
<<foreach [category in categories]>>
## <<[category.name]>>
<<foreach [item in category.items]>>
- <<[item.name]>>
<</foreach>>
<</foreach>>
Patrón 3: Sección de resumen
<<foreach [report in reports]>>
Report: <<[report.title]>>
Total Records: <<[report.records.Count()]>>
Average Value: <<[report.records.Average(r => r.value)]>>
<</foreach>>
Solución de problemas
Problemas comunes
Asunto: Errores de referencia nula
Solución: Usar Any() para comprobar las colecciones antes de la iteración
Asunto: Saltos de línea o espacios no deseados Solución: Gestiona cuidadosamente los espacios en blanco en tu plantilla.
Asunto: Problemas de rendimiento con colecciones grandes Solución: Prefiltrar datos y limitar el tamaño de las colecciones.
Asunto: Enlace de datos incorrecto Solución: Verifique que los nombres de las propiedades coincidan exactamente con su estructura de datos.
Ejemplo práctico: Partidas de una factura
Plantilla completa:
Invoice #<<[invoiceNumber]>>
Date: <<[invoiceDate]:"dd.MM.yyyy">>
Items:
<<if [lineItems.Any()]>>
<<foreach [item in lineItems]>>
<<[item.name]:caps>> - Qty: <<[item.quantity]>> - Price: $<<[item.price]:"F2">> - Total: $<<[item.quantity * item.price]:"F2">>
<</foreach>>
Subtotal: $<<[lineItems.Sum(i => i.quantity * i.price)]:"F2">>
<<else>>
No items in this invoice.
<</if>>
:::Consejo Iteraciones complejas Para escenarios de iteración complejos, considere preprocesar los datos en la lógica de su aplicación antes de pasarlos a la plantilla. Esto mejora la legibilidad y el rendimiento de la plantilla.
:::