Dynamic PDF Report Generation Using wkhtmltopdf and wkhtmltopdf‑DotNet in .NET
This article explains how to create dynamic PDF reports by designing HTML templates and converting them with the open‑source wkhtmltopdf tool and its .NET wrapper wkhtmltopdf‑DotNet, covering requirements, configuration, header/footer, table of contents, bookmarks, HTML design tips, CSS fixes, and PDF merging using iTextSharp.
Background: need dynamic PDF report generation; existing commercial components were insufficient.
Requirements: open‑source, free, cross‑platform; customizable header/footer, table of contents, bookmarks, page layout, tables, charts, template‑based.
Solution: design report template as HTML and convert with wkhtmltopdf, an open‑source command‑line tool using Qt WebKit.
wkhtmltopdf can be invoked via executable or library; .NET integration uses wkhtmltopdf‑DotNet (fork of DinkToPdf) which bundles the binary and provides a synchronous converter for multithreaded environments.
Key configuration objects are HtmlToPdfDocument , GlobalSettings and ObjectSettings . Example:
var doc = new HtmlToPdfDocument()
{
GlobalSettings = new GlobalSettings()
{
Orientation = Orientation.Portrait,
ColorMode = ColorMode.Color,
UseCompression = true,
DPI = 96,
PageOffset = 0,
Copies = 1,
Outline = true,
OutlineDepth = 4,
Out = "",
DocumentTitle = "供应商履约报告",
ImageDPI = 600,
ImageQuality = 94,
PaperSize = PaperKind.A4,
Margins = new MarginSettings() { Bottom = 1, Left = 1, Right = 1, Top = 1 },
},
Objects = {
new ObjectSettings()
{
UseExternalLinks = true,
UseLocalLinks = true,
ProduceForms = false,
IncludeInOutline = false,
PagesCount = true,
Page = url,
WebSettings = new WebSettings()
{
Background = true,
LoadImages = true,
EnableJavascript = true,
EnableIntelligentShrinking = true,
MinimumFontSize = -1,
PrintMediaType = false,
DefaultEncoding = "utf-8",
UserStyleSheet = "",
enablePlugins = false,
},
HeaderSettings = new HeaderSettings()
{
FontSize = 9,
FontName = "Ariel",
Left = "测试报告",
Right = "第 [page] 页,共[toPage] 页",
Line = true,
Spacing = 5,
HtmUrl = "https://auth.yzw.cn/",
},
FooterSettings = new FooterSettings()
{
FontSize = 9,
FontName = "Ariel",
Left = "测试报告",
Right = "第 [page] 页,共[toPage] 页 ",
Line = false,
Spacing = 5,
HtmUrl = "",
},
LoadSettings = new LoadSettings()
{
Username = "",
Password = "",
JSDelay = 200,
ZoomFactor = 1,
BlockLocalFileAccess = false,
StopSlowScript = true,
DebugJavascript = false,
LoadErrorHandling = ContentErrorHandling.Abort,
Proxy = "",
RepeatCustomHeaders = false,
},
}
}
};Headers and footers are defined via HeaderSettings and FooterSettings , using HTML URLs; page numbers use [page] and [toPage] placeholders.
Table of contents is enabled by setting isTableOfContent = true and toc.captionText in ObjectSettings . When wkhtmltopdf cannot style the TOC, a custom TOC can be generated with iTextSharp by extracting bookmarks, rendering HTML via Razor, converting to PDF, and merging streams.
Bookmarks require Outline = true and appropriate OutlineDepth ; HTML heading tags ( ‑ ) become outline entries.
HTML design tips for wkhtmltopdf: avoid absolute positioned elements without height, set container width, use inline‑block for same‑line divs, center content with placeholder divs, prefer plain CSS over frameworks, handle wide tables with word-wrap: break-word and word-break: break-all , set chart dimensions, disable animations if needed.
CSS fixes for repeated headers and page breaks include:
thead { display: table-row-group; } * { page-break-inside: avoid; page-break-after: avoid; page-break-before: avoid; } table { word-wrap: break-word; } table td { word-break: break-all; }PDF merging with iTextSharp uses PdfReader , PdfCopy , and SimpleBookmark.ShiftPageNumbers to preserve outlines.
Conclusion: wkhtmltopdf provides a free, cross‑platform way to render HTML to PDF but lacks multithreading and native performance; it should not process untrusted HTML and requires appropriate fonts for Chinese characters.
YunZhu Net Technology Team
Technical practice sharing from the YunZhu Net Technology Team
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.