Net5使用WkHtmlToPdfDotNet创建PDF
前言
最近遇到了创建PDF的需求,虽然最后没有采用这个方案,但是基本实现了,记录一下。
1.WkHtmlToPdfDotNet
WkHtmlToPdfDotNet是基于本地 wkhtmltopdf封装的.NET Core类库,主要通过webkit引擎实现html页面转换为pdf文件。并且支持在Windows、Docker、Linux、MacOSX运行。
主要功能实现在线URL转pdf文件或者html代码直接转换为pdf文件,并对css样式、图片等很好的支持,导出的pdf文件和网站相差不大。
2.Nuget
感觉支持挺多的
创建命令
.NET CLI:
dotnet add package Haukcode.WkHtmlToPdfDotNet --version 1.5.86
Packag Manafer:
PM> NuGet\Install-Package Haukcode.WkHtmlToPdfDotNet -Version 1.5.86
github地址:
https://github.com/HakanL/WkHtmlToPdf-DotNet
3.基于HTML生成PDF
这里使用控制台程序生成PDF
在单线程应用程序中使用此转换器:var converter = new BasicConverter(new PdfTools());
static void Main(string[] args)
{
var converter = new BasicConverter(new PdfTools());
//var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
PagesCount = true,
HtmlContent =gethtmlstr(),
WebSettings = {DefaultEncoding = "utf-8" },
HeaderSettings = {FontSize = 9, Right = "Page [page] of [toPage]", Line = false },
FooterSettings = {FontSize = 9, Right = "Page [page] of [toPage]" }
}
}
};
// 转换为二进制
byte[] pdf = converter.Convert(doc);
string dire = System.AppDomain.CurrentDomain.BaseDirectory + "Files";
// 判断目录是否存在,不存在则创建
if (!Directory.Exists(dire))
{
Directory.CreateDirectory(dire);
}
// 文件保存
using (var stream = new FileStream(Path.Combine(dire, "测试" + DateTime.UtcNow.Ticks.ToString() + ".pdf"), FileMode.Create))
{
stream.Write(pdf, 0, pdf.Length);
}
}
static string gethtmlstr()
{
return "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\" />\r\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n <title>Document</title>\r\n </head>\r\n <style></style>\r\n <body> 测试PDF </body>\r\n</html>\r\n";
}
4.API接口
在多线程应用程序和web服务器中使用此转换器。 转换任务保存为阻塞收集,并在单个线程上执行 :var converter = new SynchronizedConverter(new PdfTools());
ServiceCollection注入:
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
实现:
public class WkHtmlToPdfProvider
{
public async Task<byte[]> CreatePdfByHtml(string htmlstr)
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
PagesCount = true,
HtmlContent =htmlstr,
WebSettings = {DefaultEncoding = "utf-8" },
HeaderSettings = {FontSize = 9, Right = "Page [page] of [toPage]", Line = false },
FooterSettings = {FontSize = 9, Right = "Page [page] of [toPage]" }
}
}
};
// 转换为二进制
byte[] pdf = converter.Convert(doc);
return await Task.FromResult<byte[]>(pdf);
}
}
传入html字符就可以了
AllowAnonymous设置接口不要权限访问,要不前端a标签访问还需要token
Controller:
[HttpGet]
[Route("xxx/CreatePdf/{key}")]
[AllowAnonymous]
public async Task<FileResult> CreatePdf([FromServices] WkHtmlToPdfProvider provider)
{
var htmlstr = await xxxxx();//生成html
var bytes = await provider.CreatePdfByHtml(htmlstr);
return File(bytes, "application/octet-stream", "客户在线对账.pdf");
}
前端:创建a标签下载
downloadfile() {
// pdf
let date = new Date();
//const fileName = '测试.pdf';
const link = document.createElement('a'); // 创建a标签
//link.download = fileName; // a标签添加属性
link.style.display = 'none';
link.href =`http://localhost:9008/api/xxx/xxx/CreatePdf/${this.data.id}`;
document.body.appendChild(link);
link.click(); // 执行下载
URL.revokeObjectURL(link.href); // 释放url
document.body.removeChild(link); // 释放标签
}
5.Docker部署
如果你用的是微软提供的netcore的linux版本的docker容器,你将需要安装一些库。
下面的例子是基于debian的linux发行版;
在WORKDIR /app命令之前插入以下行 :
RUN apt update
RUN apt install -y libgdiplus
RUN ln -s /usr/lib/libgdiplus.so /lib/x86_64-linux-gnu/libgdiplus.so
RUN apt-get install -y --no-install-recommends zlib1g fontconfig libfreetype6 libx11-6 libxext6 libxrender1 wget gdebi
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN gdebi --n wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN apt install libssl1.1
RUN ln -s /usr/local/lib/libwkhtmltox.so /usr/lib/libwkhtmltox.so
创作不易,如果感觉帮助到你了,还请多多支持,我会继续努力。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!