Reportes.Mre.Pdfs
1.0.0
dotnet add package Reportes.Mre.Pdfs --version 1.0.0
NuGet\Install-Package Reportes.Mre.Pdfs -Version 1.0.0
<PackageReference Include="Reportes.Mre.Pdfs" Version="1.0.0" />
<PackageVersion Include="Reportes.Mre.Pdfs" Version="1.0.0" />
<PackageReference Include="Reportes.Mre.Pdfs" />
paket add Reportes.Mre.Pdfs --version 1.0.0
#r "nuget: Reportes.Mre.Pdfs, 1.0.0"
#:package Reportes.Mre.Pdfs@1.0.0
#addin nuget:?package=Reportes.Mre.Pdfs&version=1.0.0
#tool nuget:?package=Reportes.Mre.Pdfs&version=1.0.0
Reportes.Mre.Pdfs
Libreria .NET 7.0 para generacion de reportes PDF a partir de plantillas DOCX o HTML (ZIP). Reemplaza Aspose.Words de forma transparente, manteniendo el mismo contrato de codigo.
Instalacion
Dependencias NuGet
<PackageReference Include="DocumentFormat.OpenXml" Version="3.0.1" />
<PackageReference Include="Haukcode.DinkToPdf" Version="1.1.0" />
<PackageReference Include="Scriban" Version="5.9.0" />
DLL nativa (wkhtmltopdf)
La libreria requiere la DLL nativa de wkhtmltopdf para generar PDFs:
| Plataforma | Archivo | Ubicacion |
|---|---|---|
| Windows x64 | libwkhtmltox.dll |
Native/ o raiz del proyecto |
| Linux x64 | libwkhtmltox.so |
Native/ o raiz del proyecto |
| macOS x64 | libwkhtmltox.dylib |
Native/ o raiz del proyecto |
El paquete Haukcode.DinkToPdf ya incluye las DLLs nativas para las 3 plataformas.
Uso basico
using Reportes.Mre.Pdfs;
// === Con plantilla DOCX ===
Document doc = new Document(@"Recursos\FORMATOFORMULARIO2024.docx");
ReportingEngine engine = new ReportingEngine();
engine.BuildReport(doc, dataSource, "data");
doc.Save(@"C:\temp\reporte.pdf");
// === Con plantilla ZIP (HTML) ===
Document doc = new Document(@"Recursos\Plantilla.zip");
ReportingEngine engine = new ReportingEngine();
engine.BuildReport(doc, dataSource, "data");
doc.Save(@"C:\temp\reporte.pdf");
El contrato es identico para ambos formatos. La extension del archivo (.docx o .zip) determina automaticamente el pipeline de procesamiento.
API publica
Document
namespace Reportes.Mre.Pdfs
{
public class Document
{
// Crea un documento a partir de una plantilla DOCX o ZIP
public Document(string filePath);
// Guarda el documento procesado como PDF
// Si la ruta tiene extension .docx, se cambia automaticamente a .pdf
public void Save(string outputPath);
}
}
ReportingEngine
namespace Reportes.Mre.Pdfs
{
public class ReportingEngine
{
public ReportingEngine();
// Procesa la plantilla con los datos proporcionados
// dataSourceName es el nombre usado en la plantilla (ej: "data")
public void BuildReport(Document doc, object dataSource, string dataSourceName);
}
}
Plantillas DOCX
Sintaxis de marcadores
La libreria soporta la sintaxis de Aspose.Words Reporting Engine (LINQ):
Campos simples
<<[data.NombreCampo]>>
Ejemplo en el DOCX:
Nombre: <<[data.NombreCargo]>>
Categoria: <<[data.CategoriaPuesto]>>
Listas / Foreach
<<foreach [item in data.Lista]>>
<<[item.Propiedad]>>
<</foreach>>
Ejemplo:
<<foreach [item in data.FuncionesPuesto]>>
Funcion: <<[item.Funcion]>>
Resultado: <<[item.Resultado]>>
Porcentaje: <<[item.FuncionPuestoPorcentaje]>>
<</foreach>>
Foreach en tablas (expansion de filas)
Cuando un <<foreach>> esta dentro de una fila de tabla y referencia campos en otras celdas de la misma fila, la fila completa se duplica por cada elemento de la lista:
| <<foreach [item in data.Funciones]>><<[item.Nombre]>> | <<[item.Resultado]>> | <<[item.Porcentaje]>> |
| <</foreach>> |
Esto genera una fila por cada item de la coleccion.
Marcadores especiales
| Marcador | Descripcion |
|---|---|
<<cellMerge>> |
Fusiona la celda con la anterior (colspan en HTML) |
<<restartNum>> |
Reinicia numeracion de lista (se ignora en el PDF) |
Estructura del DOCX
- Body: Contenido principal con tablas, parrafos y marcadores
- Header: Se extrae automaticamente y se repite en cada pagina del PDF
- Soporta tablas, texto e imagenes
- Las imagenes se convierten a base64 inline
- Footer: Se extrae si existe
Formato de campos en el DOCX
Los campos pueden estar divididos entre multiples "Runs" de Word con diferentes formatos (bold, italic, font-size). La libreria los reassembla automaticamente antes de procesarlos.
Plantillas ZIP (HTML)
Estructura del ZIP
Plantilla.zip
plantilla-body.html <-- REQUERIDO: cuerpo del documento
plantilla-header.html <-- OPCIONAL: header repetible en cada pagina
plantilla-footer.html <-- OPCIONAL: footer (puede estar vacio)
Los archivos se detectan por nombre: cualquier archivo con body, header o footer en el nombre.
plantilla-body.html
Puede ser un fragmento HTML o un documento completo. Usa la misma sintaxis de marcadores Aspose, HTML-encoded:
<style>
.tbl { width: 100%; border-collapse: collapse; font-size: 9.5pt; }
.tbl td { border: 1px solid #5B9BD5; padding: 3pt 5pt; }
.td-num { font-weight: bold; width: 6%; }
.td-lbl { font-weight: bold; }
</style>
<table class="tbl">
<tr>
<td class="td-num">1.1</td>
<td class="td-lbl">UBICACION</td>
<td><<[data.Ubicacion]>></td>
</tr>
</table>
<table class="tbl">
<tr>
<td><<foreach [item in data.FuncionesPuesto]>><<[item.Funcion]>></td>
<td><<[item.Resultado]>></td>
<td><<[item.FuncionPuestoPorcentaje]>><</foreach>></td>
</tr>
</table>
Nota: Los marcadores
<<y>>deben estar HTML-encoded como<<y>>en el HTML.
plantilla-header.html
Documento HTML completo que se usa como header repetible en cada pagina:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<style>
.doc-header { width: 100%; border-collapse: collapse; }
.doc-header td { border: 1px solid #5B9BD5; padding: 3px 5px; }
.col-logo { width: 45%; text-align: center; }
.col-titulo { width: 27%; text-align: center; }
.col-version { width: 27%; text-align: center; }
</style>
</head>
<body>
<table class="doc-header">
<tr>
<td class="col-logo" rowspan="2">
<img src="data:image/png;base64,..." />
MINISTERIO DE RELACIONES EXTERIORES
</td>
<td class="col-titulo">
<strong>MANUAL DE PUESTOS</strong><br/>
POAI 2026
</td>
<td class="col-version">Version: GM-01.2026</td>
</tr>
<tr>
<td></td>
<td>Fecha Aprobacion: ___/___/2026</td>
</tr>
</table>
</body>
</html>
Las imagenes deben estar como base64 inline (data:image/png;base64,...).
Si el header usa un wrapper .pagina (estilo Puppeteer/Playwright), la libreria ajusta automaticamente los paddings para wkhtmltopdf.
plantilla-footer.html
Puede estar vacio o contener solo un comentario HTML si no se necesita footer:
DataSource (objeto de datos)
El dataSource puede ser cualquier objeto .NET. Las propiedades se acceden por nombre (PascalCase) desde la plantilla:
var dataSource = new
{
// Campos simples
Ubicacion = "SERVICIO CENTRAL",
NombreCargo = "Analista Senior",
CategoriaPuesto = "Profesional",
NroItem = "1234",
// Listas de objetos
FuncionesPuesto = new List<FuncionPuestoDto>
{
new() { Funcion = "Elaborar planillas", Resultado = "Planillas aprobadas", FuncionPuestoPorcentaje = 30 },
new() { Funcion = "Controlar asistencia", Resultado = "Reportes generados", FuncionPuestoPorcentaje = 20 },
},
// Objetos anidados
Idiomas = new IdiomasDto
{
Extranjero = new List<IdiomaCodificadorDTO>
{
new() { Idioma = new() { Nombre = "Ingles" }, Nivel = new() { Nombre = "Intermedio" } }
}
},
// Listas de strings
GradoFormacion = new List<string> { "Licenciatura en Administracion", "Licenciatura en Derecho" }
};
Tipos soportados
| Tipo | Acceso en plantilla | Ejemplo |
|---|---|---|
string, int, decimal, etc. |
<<[data.Campo]>> |
<<[data.NombreCargo]>> |
List<T> |
<<foreach [item in data.Lista]>> |
<<foreach [item in data.FuncionesPuesto]>> |
| Objetos anidados | <<[data.Objeto.Propiedad]>> |
<<[data.Idiomas.Extranjero]>> |
List<string> |
<<foreach [item in data.Lista]>><<[item]>> |
Items sin propiedad |
Pipeline de procesamiento
Entrada (.docx o .zip)
|
[Document constructor]
|
+----+----+
| |
DOCX ZIP
| |
OpenXML Extraer 3 HTMLs
-> HTML |
| Decodificar << -> <<
| |
+----+----+
|
Convertir Aspose -> Scriban
(<<[campo]>> -> {{ campo }})
Promover loops a nivel fila
|
[ReportingEngine.BuildReport()]
|
Scriban procesa template + datos
Aplicar cellMerge
|
[Document.Save()]
|
DinkToPdf genera PDF
(header repetible en cada pagina)
|
Archivo PDF
Configuracion del PDF generado
| Propiedad | Valor |
|---|---|
| Formato | A4 Portrait |
| DPI | 300 |
| Margenes | Top: 12mm (45mm con header), Bottom/Left/Right: 12mm |
| Fuente base | Segoe UI, Calibri, Verdana, Arial |
| Font-size base | 8pt |
| Encoding | UTF-8 |
| IntelligentShrinking | Desactivado |
| MinimumFontSize | 7pt |
Estructura del proyecto
Reportes.Mre.Pdfs/
Reportes.Mre.Pdfs.csproj .NET 7.0 Class Library
Document.cs Clase publica principal
ReportingEngine.cs Clase publica principal
Core/
DocxToHtmlConverter.cs OpenXML -> HTML (con imagenes base64)
ZipTemplateLoader.cs Carga plantillas desde ZIP
AsposeTemplateSyntaxParser.cs Convierte Aspose -> Scriban
TemplateProcessor.cs Motor Scriban (datos -> HTML)
PdfGenerator.cs DinkToPdf (HTML -> PDF)
Models/
ConversionContext.cs Estado del pipeline
Native/
libwkhtmltox.dll DLL nativa (Windows x64)
Ejemplo completo
using Reportes.Mre.Pdfs;
// 1. Cargar plantilla (DOCX o ZIP)
Document doc = new Document(@"Recursos\FORMATOFORMULARIO2024.docx");
// 2. Preparar datos
var dataSource = new ForrmatoPoaiDto
{
Ubicacion = "SERVICIO CENTRAL",
LocalizacionGeografica = "La Paz, Bolivia",
NombreCargo = "Analista de RRHH",
CategoriaPuesto = "Profesional",
NroItem = "1234",
ObjetivoPuesto = "Gestionar procesos de administracion de personal",
RelacionesIntrainstitucionales = new List<CodificadorDTO>
{
new() { Nombre = "Direccion de Asuntos Juridicos" },
new() { Nombre = "Unidad Financiera" }
},
FuncionesPuesto = new List<FuncionPuestoDto>
{
new() { Funcion = "Elaborar planillas", Resultado = "Planillas aprobadas", FuncionPuestoPorcentaje = 30 }
},
Compentencias = new List<CompetenciaDto>
{
new() { Competencia = new() { Nombre = "Liderazgo" }, Descripcion = "Dirigir equipos de trabajo" }
}
};
// 3. Procesar
ReportingEngine engine = new ReportingEngine();
engine.BuildReport(doc, dataSource, "data");
// 4. Generar PDF
doc.Save(@"C:\temp\POAI_output.pdf");
Migracion desde Aspose.Words
Antes (Aspose)
using Aspose.Words;
using Aspose.Words.Reporting;
Aspose.Words.License license = new Aspose.Words.License();
license.SetLicense(@"Recursos\License.txt");
Document doc = new Document(@"Recursos\FORMATOFORMULARIO2024.docx");
ReportingEngine engine = new ReportingEngine();
engine.BuildReport(doc, dataSource, "data");
doc.Save(path); // genera DOCX
Despues (Reportes.Mre.Pdfs)
using Reportes.Mre.Pdfs;
// No requiere licencia
Document doc = new Document(@"Recursos\FORMATOFORMULARIO2024.docx");
ReportingEngine engine = new ReportingEngine();
engine.BuildReport(doc, dataSource, "data");
doc.Save(path); // genera PDF (cambia .docx -> .pdf automaticamente)
Cambios necesarios en el codigo consumidor:
- Cambiar
using Aspose.Words/using Aspose.Words.Reportingporusing Reportes.Mre.Pdfs - Eliminar las lineas de licencia Aspose
- La salida ahora es PDF en vez de DOCX
Notas importantes
- Thread safety: El conversor PDF usa un
SynchronizedConvertersingleton (thread-safe) - Imagenes: Se extraen del DOCX (header/body) como base64 inline en el HTML
- Headers repetibles: Se muestran en cada pagina del PDF via wkhtmltopdf
- Foreach en tablas: Los loops que expanden filas se promueven automaticamente fuera del
<tr> - Encoding: Siempre UTF-8
- Archivos temporales: Los headers se guardan en archivos temporales que se eliminan automaticamente
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net7.0
- DocumentFormat.OpenXml (>= 3.0.1)
- Haukcode.DinkToPdf (>= 1.1.0)
- Scriban (>= 5.9.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 142 | 3/18/2026 |
v1.0.0 - Release inicial
- Soporte de plantillas DOCX (OpenXML) y ZIP (HTML)
- Sintaxis Aspose compatible: campos simples, foreach, cellMerge
- Motor de templates Scriban
- Generacion PDF via DinkToPdf (wkhtmltopdf)
- Extraccion automatica de headers/footers/imagenes del DOCX
- Headers repetibles en cada pagina del PDF