{"id":25052103,"url":"https://github.com/rickedb/wkhtmltowrapper","last_synced_at":"2026-04-27T22:33:35.691Z","repository":{"id":238777835,"uuid":"648014602","full_name":"Rickedb/wkhtmltowrapper","owner":"Rickedb","description":"Yet another free C# wrapper of wkhtmltopdf and wkhtmltoimage","archived":false,"fork":false,"pushed_at":"2024-05-14T21:59:32.000Z","size":24460,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-25T12:15:29.266Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Rickedb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-01T02:52:12.000Z","updated_at":"2024-05-14T22:04:27.000Z","dependencies_parsed_at":"2024-05-29T02:28:50.240Z","dependency_job_id":null,"html_url":"https://github.com/Rickedb/wkhtmltowrapper","commit_stats":null,"previous_names":["rickedb/wkhtmltowrapper"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rickedb%2Fwkhtmltowrapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rickedb%2Fwkhtmltowrapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rickedb%2Fwkhtmltowrapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rickedb%2Fwkhtmltowrapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Rickedb","download_url":"https://codeload.github.com/Rickedb/wkhtmltowrapper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246423727,"owners_count":20774819,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-06T10:21:25.076Z","updated_at":"2026-04-27T22:33:32.980Z","avatar_url":"https://github.com/Rickedb.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WkHtmlToWrapper\n\nYes! This is **ANOTHER** wrapper for the incredible and archived [wkhtmltopdf](https://github.com/wkhtmltopdf/wkhtmltopdf).\n\n## Why have you done this?\n\n\u003e _Mainly because it was fun to.__\n\nI've used [Rotativa.AspNetCore](https://github.com/webgio/Rotativa.AspNetCore) library many times since started with AspNet which\nI've found it very useful, works fine most of the time and uses wkhtmltopdf under the roof.\n\nAlthough I like Rotativa I feel that it misses many wkhtmltopdf configurations when using it with the default Rotativa's classes, \nmost of the time if you need to use any other command option you would need to append it with a custom string containing all\nthe desired options. \n\nIt was also directly coupled to MVC/AspNetCore, which obligates you to use the entire AspNet engine to render html, so in cases you have\nthe html already done or other engines to generate you could not convert to PDF without going through the AspNet engine.\n\nThat's why I've decided to create a brand new wrapper that enables you to easily use `wkhtmltopdf` inside and outside of an AspNet project.\n\n## Will keep maintaining this repo?\n\nPartially. I have no intention of maintaining something that the main thing is [already deprecated](https://wkhtmltopdf.org/status.html). \nBut until it **dies** completely I'll try to keep up with the repo by adding some new .NET features and upgrading .NET versions.\n\nYou might consider many others awesome PDF generators that are still maintained, such as [WeasyPrint](https://github.com/Kozea/WeasyPrint/).\n\n\u003e But if you still stick with this, feel free to use.\n\n## NuGet \n\n```bash\n# Wrapper library\ndotnet add package WkHtmlTo.Wrapper\n\n# AspNetCore MVC\ndotnet add package WkHtmlTo.Wrapper.AspNetCore\n\n# Blazor server\ndotnet add package WkHtmlTo.Wrapper.BlazorServer\n```\n\n## How to use?\n\nThe heart of the library is the **Wrapper**, so everything ends up on him and you can use it anywhere you want. \nHowever there are some abstractions created for Razor and Blazor server components. \n\n### Setting up environment\n\n[Download the binary](https://wkhtmltopdf.org/downloads.html) of the operational system where your code will be running.\n\n\u003e If you run in both OS like Windows for development and publish on Linux, you should consider downloading both.\n\nAfter that you'll need to install the binaries or have them at your folder. \n\n#### Dockerfile\n\n```dockerfile\nFROM mcr.microsoft.com/dotnet/aspnet:8.0-jammy AS base\nWORKDIR /app\nRUN apt-get update \u0026\u0026 \\\n\tapt-get install -y wget wkhtmltopdf\n\nUSER app\nEXPOSE 8080\nEXPOSE 8081\n```\n\n\u003e It is possible to download the `.deb` and install it, if necessary\n\n#### Windows\n\nAdd the files to be copied to your publish folder by adding on your `.csproj`:\n\n```xml\n\u003cItemGroup\u003e\n  \u003cNone Update=\"\u003cpath\u003e\\wkhtmltopdf.exe\"\u003e\n    \u003cCopyToOutputDirectory\u003ePreserveNewest\u003c/CopyToOutputDirectory\u003e\n  \u003c/None\u003e\n  \u003cNone Update=\"\u003cpath\u003e\\wkhtmltox.dll\"\u003e\n    \u003cCopyToOutputDirectory\u003ePreserveNewest\u003c/CopyToOutputDirectory\u003e\n  \u003c/None\u003e\n\u003c/ItemGroup\u003e\n```\n\n### Usage examples\n\nFor more examples, please check the [samples folder](https://github.com/Rickedb/wkhtmltowrapper/tree/master/samples).\n\n#### Basic usage\n```csharp\nvar wrapper = new WkHtmlToPdfWrapper(); //When not providing the root path of the executable, it considers the same path of your assembly\nvar html = \"\u003chtml\u003e\u003cbody\u003e\u003ch1\u003eHello World!\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e\";\nvar options = new HtmlOptions(html);\nvar result = await wrapper.ConvertAsync(options);\nif(result.Success)\n{\n\tvar bytes = result.GetBytes();\n\t//Do your thing...\n}\n```\n\n### AspNetCore usage\n\nWhen using .net MVC, it's possible to return 3 types of results: `ViewResult`, `FileStreamResult` and `FileContentResult`.\n\nAll of them might lead to the same purpose that is to download the pdf, so please always consider using `FileStreamResult` which will stream the download gradually to the client\ninstead the others that will output the file full size in one shot.\n\n#### Dependency injection\n\n```csharp\n//Program.cs\nbuilder.Services.AddWkHtmlToWrapper();\n```\n\n```csharp\n//Startup.cs\npublic void ConfigureServices(IServiceCollection services)\n{\n    //...\n    services.AddWkHtmlToWrapper();\n    //...\n}\n```\n\n#### ViewResult\n```csharp\npublic IActionResult MyView()\n{\n    //It will search for MyView.cshtml\n    var result = new PdfViewResult(new MyViewModel());\n    return result;\n}\n```\n\n#### FileStreamResult\n\n```csharp\npublic IActionResult StreamDownload()\n{\n    //It will search for \"AnotherView.cshtml\"\n    var result = new PdfFileStreamResult(\"AnotherView\");\n    return result;\n}\n```\n\n#### FileContentResult\n\n```csharp\npublic IActionResult Download()\n{\n    //It will search for \"AnotherView.cshtml\" using MyViewModel\n    var result = new PdfFileContentResult(\"AnotherView\", new MyViewModel());\n    return result;\n}\n```\n\n### Blazor server usage\n\nAt Blazor server it relies on the new `HtmlRenderer` class to render the component string. \n\n#### Dependency injection\n\n```csharp\n//Program.cs\nbuilder.Services.AddWkHtmlToPdfWrapper();\n```\n\n#### Include the JS\n\nOpen `Components\\App.razor` and include:\n\n```html\n\u003cscript src=\"_content/WkHtmlTo.Wrapper.BlazorServer/WkHtmlTo.Wrapper.js\"\u003e\u003c/script\u003e\n```\n\n\u003e This will enable to trigger download at the client's browser.\n\n#### Exporting component\n\nWhen exporting, it will runs the complete initialization lifecycle until it renders to Html and the your pdf\n\n##### FetchData.razor (Page to be exported)\n\n```\n@page \"/fetchdata\"\n\n\u003cPageTitle\u003eWeather forecast\u003c/PageTitle\u003e\n\n@using WkHtmlToPdf.Wrapper.BlazorServer.Tests.Data\n@inject WeatherForecastService ForecastService\n\n\u003ch1\u003eWeather forecast\u003c/h1\u003e\n\n\u003cp\u003eThis component demonstrates fetching data from a service.\u003c/p\u003e\n\n@if (forecasts == null)\n{\n    \u003cp\u003e\u003cem\u003eLoading...\u003c/em\u003e\u003c/p\u003e\n}\nelse\n{\n    \u003ctable class=\"table\"\u003e\n        \u003cthead\u003e\n            \u003ctr\u003e\n                \u003cth\u003eDate\u003c/th\u003e\n                \u003cth\u003eTemp. (C)\u003c/th\u003e\n                \u003cth\u003eTemp. (F)\u003c/th\u003e\n                \u003cth\u003eSummary\u003c/th\u003e\n            \u003c/tr\u003e\n        \u003c/thead\u003e\n        \u003ctbody\u003e\n            @foreach (var forecast in forecasts)\n            {\n                \u003ctr\u003e\n                    \u003ctd\u003e@forecast.Date.ToShortDateString()\u003c/td\u003e\n                    \u003ctd\u003e@forecast.TemperatureC\u003c/td\u003e\n                    \u003ctd\u003e@forecast.TemperatureF\u003c/td\u003e\n                    \u003ctd\u003e@forecast.Summary\u003c/td\u003e\n                \u003c/tr\u003e\n            }\n        \u003c/tbody\u003e\n    \u003c/table\u003e\n}\n\n@code {\n    private WeatherForecast[]? forecasts;\n\n    protected override async Task OnInitializedAsync()\n    {\n        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);\n    }\n}\n```\n\n##### Index.razor (Page where we want to run export)\n```\n@page \"/\"\n@inject PdfComponentRenderer Renderer\n\n\u003cPageTitle\u003eIndex\u003c/PageTitle\u003e\n\n\u003ch1\u003eHello, world!\u003c/h1\u003e\n\nWelcome to your new app.\n\u003cSurveyPrompt Title=\"How is Blazor working for you?\" /\u003e\n\u003cbutton class=\"btn btn-primary\" @onclick=\"ExportDataAsync\"\u003eClick me to export data\u003c/button\u003e\n\n@code {\n    public async Task RunAsync()\n    {\n        await Renderer.GenerateAndDownloadAsync\u003cFetchData\u003e();\n    }\n}\n```\n\n#### Limitations\n\n1. At the point we are now with Blazor Server, unlike the **AspNetCore MVC**, it only renders the given component without considering the root component _(e.g.: `MainLayout.razor`)_, \nso you might need to include your entire HTML at the rendered component.\n2. When it renders, it won't trigger `AfterRender`/`AfterRenderAsync` methods, just `Initialize`/`InitializeAsync`, so, if you rely in any component that should be rendered before manipulating, it won't work.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frickedb%2Fwkhtmltowrapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frickedb%2Fwkhtmltowrapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frickedb%2Fwkhtmltowrapper/lists"}