AdaskoTheBeAsT.WkHtmlToX
10.0.0
dotnet add package AdaskoTheBeAsT.WkHtmlToX --version 10.0.0
NuGet\Install-Package AdaskoTheBeAsT.WkHtmlToX -Version 10.0.0
<PackageReference Include="AdaskoTheBeAsT.WkHtmlToX" Version="10.0.0" />
<PackageVersion Include="AdaskoTheBeAsT.WkHtmlToX" Version="10.0.0" />
<PackageReference Include="AdaskoTheBeAsT.WkHtmlToX" />
paket add AdaskoTheBeAsT.WkHtmlToX --version 10.0.0
#r "nuget: AdaskoTheBeAsT.WkHtmlToX, 10.0.0"
#:package AdaskoTheBeAsT.WkHtmlToX@10.0.0
#addin nuget:?package=AdaskoTheBeAsT.WkHtmlToX&version=10.0.0
#tool nuget:?package=AdaskoTheBeAsT.WkHtmlToX&version=10.0.0
WkHtmlToX
๐ A high-performance, thread-safe C# wrapper for wkhtmltopdf that converts HTML to PDF and images with ease.
โจ Features
- Cross-Platform Support - Works on Windows (x64/x86), macOS, and Linux (multiple distributions)
- Thread-Safe - Built with concurrency in mind using modern .NET patterns
- Memory Efficient - Leverages
ArrayPool<byte>and supports RecyclableMemoryStream - Async/Await - Fully asynchronous API with
CancellationTokensupport - Multi-Target - Supports .NET Standard 2.0, .NET 8.0, .NET 9.0, and .NET 10.0
- Production Ready - Comprehensive test coverage and extensive static analysis
- Event Callbacks - Track conversion progress, phases, warnings, and errors
- HTML to PDF - Convert HTML content, streams, or byte arrays to PDF
- HTML to Image - Convert HTML to various image formats
๐ฆ Installation
dotnet add package AdaskoTheBeAsT.WkHtmlToX
๐ Quick Start
Console Application
using AdaskoTheBeAsT.WkHtmlToX;
using AdaskoTheBeAsT.WkHtmlToX.Documents;
using AdaskoTheBeAsT.WkHtmlToX.Engine;
using AdaskoTheBeAsT.WkHtmlToX.Settings;
var configuration = new WkHtmlToXConfiguration((int)Environment.OSVersion.Platform, null);
using var engine = new WkHtmlToXEngine(configuration);
engine.Initialize();
var converter = new PdfConverter(engine);
// Create document with HTML content
var document = new HtmlToPdfDocument
{
GlobalSettings = new PdfGlobalSettings
{
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4
},
ObjectSettings =
{
new PdfObjectSettings
{
HtmlContent = "<html><body><h1>Hello World!</h1></body></html>",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
// Convert to PDF
using var stream = new FileStream("output.pdf", FileMode.Create);
var result = await converter.ConvertAsync(
document,
_ => stream,
CancellationToken.None);
Console.WriteLine(result ? "Success!" : "Failed!");
ASP.NET Core Web API with Dependency Injection
Startup Configuration
// Program.cs or Startup.cs
services.AddSingleton(sp =>
{
var configuration = new WkHtmlToXConfiguration(
(int)Environment.OSVersion.Platform,
null);
return configuration;
});
services.AddSingleton<IWkHtmlToXEngine>(sp =>
{
var config = sp.GetRequiredService<WkHtmlToXConfiguration>();
var engine = new WkHtmlToXEngine(config);
engine.Initialize();
return engine;
});
services.AddSingleton<IPdfConverter, PdfConverter>();
services.AddSingleton<IImageConverter, ImageConverter>();
Controller Implementation
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
private readonly IPdfConverter _pdfConverter;
private readonly RecyclableMemoryStreamManager _memoryManager;
public PdfController(IPdfConverter pdfConverter)
{
_pdfConverter = pdfConverter;
_memoryManager = new RecyclableMemoryStreamManager();
}
[HttpPost("convert")]
public async Task<IActionResult> ConvertToPdf([FromBody] string htmlContent)
{
var document = new HtmlToPdfDocument
{
GlobalSettings = new PdfGlobalSettings(),
ObjectSettings =
{
new PdfObjectSettings { HtmlContent = htmlContent }
}
};
Stream? stream = null;
var converted = await _pdfConverter.ConvertAsync(
document,
length =>
{
stream = _memoryManager.GetStream(
Guid.NewGuid(),
"wkhtmltox",
length);
return stream;
},
HttpContext.RequestAborted);
if (converted && stream != null)
{
stream.Position = 0;
return File(stream, "application/pdf", "output.pdf");
}
return BadRequest("Conversion failed");
}
}
๐ง Advanced Configuration
Linux Platform Configuration
For Linux environments, specify the runtime identifier:
var configuration = new WkHtmlToXConfiguration(
(int)PlatformID.Unix,
WkHtmlToXRuntimeIdentifier.Ubuntu2004X64);
Supported Linux Distributions
- Ubuntu (14.04, 16.04, 18.04, 20.04) - x64/x86
- Debian (9, 10) - x64/x86
- CentOS (6, 7, 8)
- Amazon Linux 2
- OpenSUSE Leap 15
Event Callbacks
Monitor conversion progress and handle warnings/errors:
var configuration = new WkHtmlToXConfiguration(
(int)Environment.OSVersion.Platform,
null)
{
PhaseChangedAction = args =>
Console.WriteLine($"Phase {args.CurrentPhase}/{args.PhaseCount}: {args.Description}"),
ProgressChangedAction = args =>
Console.WriteLine($"Progress: {args.Description}"),
WarningAction = args =>
Console.WriteLine($"Warning: {args.Message}"),
ErrorAction = args =>
Console.WriteLine($"Error: {args.Message}"),
FinishedAction = args =>
Console.WriteLine($"Finished: {(args.Success ? "Success" : "Failed")}")
};
Custom PDF Settings
var document = new HtmlToPdfDocument
{
GlobalSettings = new PdfGlobalSettings
{
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.A4,
Margins = new MarginSettings
{
Top = 10,
Bottom = 10,
Left = 10,
Right = 10,
Unit = Unit.Millimeters
},
DocumentTitle = "My Document",
UseCompression = true
},
ObjectSettings =
{
new PdfObjectSettings
{
HtmlContent = htmlContent,
WebSettings =
{
DefaultEncoding = "utf-8",
EnableJavascript = true,
LoadImages = true
},
HeaderSettings = new SectionSettings
{
HtmlContent = "<div>Header Content</div>"
},
FooterSettings = new SectionSettings
{
HtmlContent = "<div>Page [page] of [toPage]</div>"
}
}
}
};
Memory-Efficient Stream Handling
The library supports custom stream creation, allowing integration with RecyclableMemoryStream to minimize memory allocations:
var memoryManager = new RecyclableMemoryStreamManager();
Stream? stream = null;
var result = await converter.ConvertAsync(
document,
length =>
{
// RecyclableMemoryStream reuses memory blocks
stream = memoryManager.GetStream(Guid.NewGuid(), "wkhtmltox", length);
return stream;
},
cancellationToken);
๐๏ธ Architecture
- Clean Separation - Abstractions, Engine, Loaders, Modules, and Settings
- Resource Management - Proper
IDisposableimplementation with thread-safe disposal - Cross-Platform Loading - Platform-specific library loaders (Windows, Linux, macOS)
- Worker Thread Pattern - Background thread processes conversion queue
- Visitor Pattern - Extensible work item processing
๐งช Code Quality
This project maintains high code quality standards with:
- 20+ static code analyzers (Roslyn, SonarAnalyzer, StyleCop, etc.)
- Comprehensive test coverage (unit, integration, memory tests)
- Strict null reference checks enabled
- Treats warnings as errors
- Continuous Integration with Azure DevOps
- SonarCloud quality gate
๐ค Contributing
Contributions are welcome! Please ensure:
- Code follows existing patterns and conventions
- All tests pass
- Code analyzers produce no warnings
- XML documentation is provided for public APIs
๐ License
This project is licensed under the terms specified in the LICENSE file.
๐ Acknowledgments
This library is built upon DinkToPdf with a completely reworked interoperability layer to address memory management and thread-safety concerns.
๐ Additional Resources
- wkhtmltopdf Documentation
- Sample Projects - Console, Web API, and OWIN examples
- Issue Tracker
๐ก Tips & Best Practices
- Singleton Pattern - Register
WkHtmlToXEngineas a singleton in DI containers - Memory Management - Use
RecyclableMemoryStreamfor high-throughput scenarios - Cancellation - Always pass
CancellationTokenfor responsive cancellation - Linux Deployment - Ensure correct runtime identifier for your Linux distribution
- Thread Safety - The engine handles concurrency internally; don't create multiple engines
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. 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 is compatible. 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 is compatible. 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 is compatible. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
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 |
|---|---|---|
| 10.0.0 | 101 | 4/4/2026 |
| 9.0.0 | 283 | 11/16/2025 |
| 8.0.0 | 673 | 1/5/2025 |
| 7.1.0 | 3,576 | 12/27/2023 |
| 7.0.0 | 245 | 12/5/2023 |
| 6.0.0 | 615 | 11/13/2022 |
| 5.0.0 | 684 | 2/23/2021 |
| 4.0.3 | 626 | 1/16/2021 |
| 4.0.1 | 645 | 12/3/2020 |
| 4.0.0 | 682 | 7/8/2020 |
| 3.0.3 | 733 | 4/22/2020 |
| 3.0.2 | 712 | 4/19/2020 |
| 3.0.1 | 675 | 4/19/2020 |
| 3.0.0 | 743 | 3/29/2020 |
| 2.0.0 | 753 | 3/28/2020 |
| 1.1.0 | 834 | 12/15/2019 |
| 1.0.0 | 739 | 12/8/2019 |