HTML · C# walkthrough
Service review with explicit target misses
Create a concise review that distinguishes performance facts from the follow-up decision.
- Start with
- Measured values, targets, units and comparison direction
- Generate
- HTML + PDF

How it works
Model each measure
Store the actual value, target, unit and whether higher or lower values are better.
Calculate the status
Evaluate each target using its direction and render a clear Met or Below target label.
Explain the follow-up
Include the missed measure, concrete actions and measurement definitions before exporting to PDF.
The C# source
This is the complete example file used to generate the download. The walkthrough runner creates the output directory and produces the additional previews.
using System.Globalization;
using System.Net;
using OfficeIMO.Drawing;
using OfficeIMO.Html;
using OfficeIMO.Html.Pdf;
namespace OfficeIMO.Examples.Showcase.Workflows;
/// <summary>Builds an HTML service review from measured and target values, including explicit misses.</summary>
internal static class ServiceLevelReport {
internal static void Create(string folder) {
var measures = new[] {
new Measure("Availability", 99.94m, 99.90m, "%", true),
new Measure("First response", 3.2m, 4m, "hours", false),
new Measure("Resolution within target", 88m, 90m, "%", true)
};
string rows = string.Join("", measures.Select(measure => {
bool met = measure.HigherIsBetter ? measure.Actual >= measure.Target : measure.Actual <= measure.Target;
return $"<tr><td>{WebUtility.HtmlEncode(measure.Name)}</td><td>{measure.Actual.ToString("0.##", CultureInfo.InvariantCulture)} {measure.Unit}</td><td>{measure.Target.ToString("0.##", CultureInfo.InvariantCulture)} {measure.Unit}</td><td class='{(met ? "met" : "miss")}'>{(met ? "Met" : "Below target")}</td></tr>";
}));
string html = $$"""
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Monthly service review</title>
<style>
@page { size:A4; margin:18mm }
body { font:14px/1.5 Arial,sans-serif;color:#24324a }
header { background:#17365d;color:white;padding:24px } h1 { font-size:30px;margin:6px 0 }
h2 { font-size:20px;color:#17365d;margin-top:26px } .label { font-size:11px;letter-spacing:2px }
table { width:100%;border-collapse:collapse;margin:18px 0 } th { text-align:left;background:#e8eef8 }
th,td { padding:12px 8px;border-bottom:1px solid #cbd5e1 }
.met { color:#176b3a } .miss { color:#9a3412;font-weight:bold }
.note { background:#fff7ed;border-left:4px solid #c76a20;padding:15px }
footer { border-top:1px solid #cbd5e1;margin-top:28px;padding-top:12px;color:#526179;font-size:11px }
</style></head><body>
<header><p class="label">NORTHWIND / SERVICE OPERATIONS</p><h1>Monthly service review</h1><p>August 2026 / request portal / illustrative measurements</p></header>
<h2>Performance against agreed targets</h2>
<table><thead><tr><th>Measure</th><th>Actual</th><th>Target</th><th>Result</th></tr></thead><tbody>{{rows}}</tbody></table>
<div class="note"><strong>Attention required</strong><p>Resolution within target missed the agreed threshold. Review the oldest waiting requests and assign an owner to each next action.</p></div>
<h2>Follow-up actions</h2><ol><li>Separate customer waiting time from internal queue time.</li><li>Review the ten oldest requests with the service owner.</li><li>Recheck the measure after two weeks of targeted follow-up.</li></ol>
<h2>Measurement notes</h2><p>Availability uses the agreed service window. First response is the median elapsed time. Resolution reports the share completed within the agreed target. Replace these definitions with the actual service contract.</p>
<footer>Prepared from synthetic data. A generated report records a measurement; it does not independently verify the source system.</footer>
</body></html>
""";
File.WriteAllText(Path.Combine(folder, "example.html"), html);
HtmlConversionDocument.Parse(html).SaveAsPdf(Path.Combine(folder, "preview.pdf"),
new HtmlToPdfOptions { PageSize = OfficePageSizes.A4, Margins = HtmlRenderMargins.All(24D) }).RequireSuccess();
}
private sealed record Measure(string Name, decimal Actual, decimal Target, string Unit, bool HigherIsBetter);
}
Open the C# source fileRun it from the source checkout
Clone the OfficeIMO repository and run this command from its root with the .NET 10 SDK. The first run restores the example project's dependencies.
dotnet run --project OfficeIMO.Examples -f net10.0 -- --showcase-workflows --showcase-example html-service-level-reportThe files are written to OfficeIMO.Examples/bin/Debug/net10.0/Documents/Workflows/html-service-level-report/. To use the example in your application, start with the HTML guide and its package setup.
Downloads and scope
What the preview shows
The linked C# example generates this file. The HTML document is exported through OfficeIMO.Html to PDF with a required successful save. Each PDF page is rendered for review.
What to keep in mind
The values are synthetic. The report evaluates supplied numbers; it does not independently collect or verify service telemetry.