![]() |
VOOZH | about |
dotnet add package GeeksCoreLibrary.Modules.GclConverters.EvoPdf --version 5.3.2605.2
NuGet\Install-Package GeeksCoreLibrary.Modules.GclConverters.EvoPdf -Version 5.3.2605.2
<PackageReference Include="GeeksCoreLibrary.Modules.GclConverters.EvoPdf" Version="5.3.2605.2" />
<PackageVersion Include="GeeksCoreLibrary.Modules.GclConverters.EvoPdf" Version="5.3.2605.2" />Directory.Packages.props
<PackageReference Include="GeeksCoreLibrary.Modules.GclConverters.EvoPdf" />Project file
paket add GeeksCoreLibrary.Modules.GclConverters.EvoPdf --version 5.3.2605.2
#r "nuget: GeeksCoreLibrary.Modules.GclConverters.EvoPdf, 5.3.2605.2"
#:package GeeksCoreLibrary.Modules.GclConverters.EvoPdf@5.3.2605.2
#addin nuget:?package=GeeksCoreLibrary.Modules.GclConverters.EvoPdf&version=5.3.2605.2Install as a Cake Addin
#tool nuget:?package=GeeksCoreLibrary.Modules.GclConverters.EvoPdf&version=5.3.2605.2Install as a Cake Tool
This is a plugin library for the GeeksCoreLibrary (GCL) that implements HTML-to-PDF conversion functionality using the EvoPdf.Chromium library. It provides a production-ready implementation of the IHtmlToPdfConverterService interface, enabling Wiser CMS applications to generate PDF documents from HTML content with full support for modern web standards, CSS, and JavaScript rendering.
The library handles complex PDF generation scenarios including:
PDF generation is a critical feature for Wiser CMS customers who need to:
This library provides a high-quality, commercially-supported PDF rendering engine that produces professional documents matching the exact appearance of web pages rendered in Chrome/Chromium browsers.
This library extends the GeeksCoreLibrary with concrete PDF generation functionality:
Dependencies:
IHtmlToPdfConverterService interface, database connections, object service, and string replacementsIntegration Pattern:
IHtmlToPdfConverterService interface with a default null implementationConfiguration Source:
All PDF generation settings are loaded from the Wiser database via the IObjectsService (system objects pattern), allowing runtime configuration without code changes.
┌─────────────────────────────────────────────────────────┐
│ Wiser Application / API │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Controllers / Services │ │
│ │ - Inject IHtmlToPdfConverterService │ │
│ └──────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────────┐ │
│ │ EvoPdfHtmlToPdfConverterService │ │
│ │ (This Library) │ │
│ │ │ │
│ │ • Loads config from database │ │
│ │ • Builds EvoPdf converter instance │ │
│ │ • Applies settings (margins, size, security) │ │
│ │ • Handles platform differences (Win/Linux) │ │
│ └──────┬────────────────────────────┬──────────────┘ │
│ │ │ │
│ ┌──────▼────────┐ ┌────────▼────────────┐ │
│ │ GeeksCoreLib │ │ EvoPdf.Chromium │ │
│ │ Services │ │ (Commercial Lib) │ │
│ │ │ │ │ │
│ │ • IObjects │ │ • HTML Rendering │ │
│ │ • IStrReplace │ │ • PDF Generation │ │
│ │ • IDatabase │ │ • Chromium Engine │ │
│ └───────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────┘
1. Interface Implementation Pattern
The library implements the IHtmlToPdfConverterService interface defined in GeeksCoreLibrary, following the Interface Segregation and Dependency Inversion principles. This allows applications to swap PDF converters without code changes.
2. Extension Method Registration Uses the standard ASP.NET Core service collection extension pattern for clean dependency injection:
builder.Services.AddEvoPdfHtmlToPdfConverterService();
3. Configuration-as-Data Pattern
All conversion settings are retrieved from the database via IObjectsService rather than hardcoded or stored in config files. This enables:
4. Template Method Pattern
Inherits from the base HtmlToPdfConverterService class which provides common functionality like background image retrieval and filename sanitization, while overriding the core conversion method.
5. Private Assets Pattern
Uses NuGet's PrivateAssets="all" feature to avoid forcing downstream dependencies on specific EvoPdf packages, giving consuming applications control over which platform-specific package to use.
Why EvoPdf?
Why .NET 9.0?
Why Separate Windows/Linux Packages? EvoPdf.Chromium has platform-specific native dependencies. The library uses MSBuild conditions and version ranges to handle this complexity, allowing the same source code to work on both platforms.
Technical Trade-offs:
Step 1: Install the NuGet package
dotnet add package GeeksCoreLibrary.Modules.GclConverters.EvoPdf
Step 2: Install platform-specific EvoPdf package
For Windows:
dotnet add package EvoPdf.Chromium.Windows
For Linux:
dotnet add package EvoPdf.Chromium.Linux
For cross-platform builds (recommended), add this to your .csproj:
<ItemGroup Condition="'$(RuntimeIdentifier)' == '' AND $([MSBuild]::IsOsPlatform('Windows'))">
<PackageReference Include="EvoPdf.Next.Windows" Version="14.6.2" />
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == '' AND $([MSBuild]::IsOsPlatform('Linux'))">
<PackageReference Include="EvoPdf.Next.Linux" Version="14.6.2" />
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'win-x64'">
<PackageReference Include="EvoPdf.Next.Windows" Version="14.6.2" />
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64'">
<PackageReference Include="EvoPdf.Next.Linux" Version="14.6.2" />
</ItemGroup>
Step 3: Register the service
In your application's Program.cs or Startup.cs, add the EvoPdf service after adding GCL services:
// Add GeeksCoreLibrary services first
builder.Services.AddGclServices(builder.Configuration);
// Then add EvoPdf implementation
builder.Services.AddEvoPdfHtmlToPdfConverterService();
Add your EvoPdf license key to appsettings.json:
{
"GclSettings": {
"EvoPdfLicenseKey": "your-evopdf-license-key-here"
}
}
The service loads PDF settings from the Wiser database via system objects. The following system objects (by domain name) control PDF generation behavior:
| System Object Key | Purpose | Default Value | Valid Values |
|---|---|---|---|
pdf_orientation |
Page orientation | portrait |
portrait, landscape |
pdf_html_viewer_width |
HTML viewport width (px) | (none) | Integer (e.g., 1024) |
pdf_html_viewer_height |
HTML viewport height (px) | (none) | Integer (e.g., 768) |
pdf_margins |
Margin size (all sides, px) | 0 |
Integer (e.g., 40) |
pdf_avoid_text_break |
Prevent text from breaking across pages | false |
true, false |
pdf_avoid_image_break |
Prevent images from breaking across pages | true |
true, false |
pdf_pagesize |
Page size | A4 |
A0-A10, CUSTOM |
pdf_pagesize_width |
Custom page width (if pdf_pagesize=CUSTOM) |
(none) | Integer (points) |
pdf_pagesize_height |
Custom page height (if pdf_pagesize=CUSTOM) |
(none) | Integer (points) |
pdf_header_show |
Enable header | false |
true, false |
pdf_header_text |
Header HTML template | (none) | HTML string |
pdf_footer_show |
Enable footer | false |
true, false |
pdf_footer_text |
Footer HTML template | (none) | HTML string |
pdf_can_edit_content |
Allow PDF editing | false |
true, false |
pdf_can_copy_content |
Allow text copying | true |
true, false |
pdf_password |
Owner/edit password | (auto-generated) | String (supports replacements) |
pdf_baseurl_override |
Override base URL for resources | (current URL) | Full URL (e.g., https://example.com) |
Example: Setting up basic PDF configuration via SQL:
-- Set default orientation to landscape
INSERT INTO wiser_system_objects (domain_name, value)
VALUES ('pdf_orientation', 'landscape')
ON DUPLICATE KEY UPDATE value = 'landscape';
-- Set margins to 40px
INSERT INTO wiser_system_objects (domain_name, value)
VALUES ('pdf_margins', '40')
ON DUPLICATE KEY UPDATE value = '40';
-- Enable footer with page numbers
INSERT INTO wiser_system_objects (domain_name, value)
VALUES ('pdf_footer_show', 'true')
ON DUPLICATE KEY UPDATE value = 'true';
INSERT INTO wiser_system_objects (domain_name, value)
VALUES ('pdf_footer_text', '<div style="text-align: center; font-size: 10pt;">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>')
ON DUPLICATE KEY UPDATE value = '<div style="text-align: center; font-size: 10pt;">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>';
On Linux, the EvoPdf loader executable requires execute permissions. Add this to your Dockerfile or deployment script:
# In your Dockerfile
RUN chmod +x /app/evopdf_loadhtml
Or manually:
chmod +x /app/evopdf_loadhtml
The service automatically detects Linux and sets the correct path:
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
converter.HtmlLoaderFilePath = "/app/evopdf_loadhtml";
}
For local development on Apple Silicon:
# Run in x64 mode on M1 Mac
dotnet run --arch x64
public class InvoiceController : Controller
{
private readonly IHtmlToPdfConverterService _pdfConverter;
public InvoiceController(IHtmlToPdfConverterService pdfConverter)
{
_pdfConverter = pdfConverter;
}
public async Task<IActionResult> DownloadInvoice(int invoiceId)
{
// Generate your HTML content
var htmlContent = await GenerateInvoiceHtmlAsync(invoiceId);
// Create PDF request
var request = new HtmlToPdfRequestModel
{
Html = htmlContent,
FileName = $"Invoice-{invoiceId}.pdf",
Orientation = PageOrientation.Portrait
};
// Convert to PDF
var pdfResult = await _pdfConverter.ConvertHtmlStringToPdfAsync(request);
return pdfResult; // Returns FileContentResult
}
}
public async Task<IActionResult> GenerateQuote(int quoteId)
{
var htmlContent = await GenerateQuoteHtmlAsync(quoteId);
var request = new HtmlToPdfRequestModel
{
Html = htmlContent,
FileName = $"Quote-{quoteId}.pdf",
Orientation = PageOrientation.Landscape,
// Custom header with dynamic content
Header = @"<div style='font-size: 10pt; text-align: right;'>
Quote #{quoteId} - <span class='date'></span>
</div>",
// Custom footer with page numbers
Footer = @"<div style='font-size: 9pt; text-align: center;'>
Page <span class='pageNumber'></span> of <span class='totalPages'></span>
</div>",
// Background image for watermark/letterhead
ItemId = quoteId,
BackgroundPropertyName = "company_letterhead",
// Override EvoPdf converter properties
DocumentOptions = "ConversionDelay:3;HtmlViewerWidth:1200"
};
var pdfResult = await _pdfConverter.ConvertHtmlStringToPdfAsync(request);
return pdfResult;
}
/Services/EvoPdfHtmlToPdfConverterService.csHtmlToPdfConverterService (GCL)ConvertHtmlStringToPdfAsync(HtmlToPdfRequestModel settings)Key Responsibilities:
IObjectsServiceHtmlToPdfConverter instanceFileContentResult ready for downloadConstructor Dependencies:
IDatabaseConnection - Database accessIObjectsService - Loads configuration from databaseIStringReplacementsService - Processes dynamic content in settingsIOptions<GclSettings> - Access to EvoPdf license keyIHttpContextAccessor - Gets base URL for resource loading (optional)IWebHostEnvironment - Environment information (optional)Initialization
InvalidOperationException if EvoPdf.Chromium not foundConfiguration Loading (from database)
HTML Preprocessing
Converter Configuration
HtmlToPdfConverter instanceDocument Options Processing
DocumentOptions string (semicolon-separated key:value pairs)HtmlToPdfConverter and PdfDocumentOptions"ConversionDelay:3;HtmlViewerWidth:1200"PDF Generation
converter.ConvertHtml(html, baseUri)Result Packaging
FileContentResultapplication/pdfInvalidOperationException thrown when first PDF is requested/app/evopdf_loadhtml doesn't have execute permissionschmod +x /app/evopdf_loadhtml in your Docker container or deployment scriptappsettings.jsonGclSettings:EvoPdfLicenseKey is set correctly; contact EvoPdf for license issues| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 5.3.2605.2 | 196 | 6/16/2026 |
| 5.3.2605.1 | 109 | 5/22/2026 |
| 5.3.2601.1 | 330 | 1/19/2026 |
| 5.3.2512.1 | 417 | 12/18/2025 |
| 5.3.2508.1 | 655 | 8/21/2025 |
| 5.3.2507.6 | 282 | 7/31/2025 |
| 5.3.2507.5 | 691 | 7/23/2025 |
| 5.3.2507.4 | 322 | 7/17/2025 |
| 5.3.2507.3 | 239 | 7/10/2025 |
| 5.3.2507.2 | 256 | 7/4/2025 |
| 5.3.2507.1 | 260 | 7/1/2025 |
| 5.3.2506.8 | 291 | 6/24/2025 |
| 5.3.2506.7 | 224 | 6/24/2025 |
| 5.3.2506.6 | 255 | 6/18/2025 |
| 5.3.2506.5 | 385 | 6/13/2025 |
| 5.3.2506.4 | 392 | 6/12/2025 |
| 5.3.2506.3 | 259 | 6/5/2025 |
| 5.3.2506.2 | 237 | 6/5/2025 |
| 5.3.2506.1 | 248 | 6/3/2025 |
| 5.3.2505.1 | 337 | 5/1/2025 |