如何在C#.NET中使用NReco实现HTML转PDF时动态添加图片水印
基于NReco.PdfGenerator实现HTML转PDF时添加图片水印的C#实现方案
前置准备
- 先通过NuGet安装依赖包:
NReco.PdfGenerator,如果需要对已生成的PDF叠加水印,额外安装NReco.PdfRenderer
实现方式1:HTML转PDF同时注入水印(推荐,无需二次处理)
该思路利用wkhtmltopdf(NReco底层依赖的组件)对固定定位元素的渲染规则,将水印作为全屏固定层级的HTML元素嵌入到原始内容中,自动在每一页重复渲染:
using NReco.PdfGenerator; using System.IO; public byte[] GeneratePdfWithImageWatermark(string originalHtml, string watermarkImagePath) { // 水印图片转base64,避免外部资源加载失败的问题 var watermarkBase64 = Convert.ToBase64String(File.ReadAllBytes(watermarkImagePath)); // 构造水印层,z-index设为最低不遮挡正常内容,透明度按需调整 var watermarkLayer = $@" <div style=""position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:-9999;opacity:0.15;pointer-events:none;""> <img src=""data:image/png;base64,{watermarkBase64}"" style=""width:100%;height:100%;object-fit:contain;"" /> </div>"; // 把水印层拼接到原始HTML的body节点下 var processedHtml = originalHtml.Replace("<body>", $"<body>{watermarkLayer}"); // 初始化PDF生成器,可按需配置页面参数 var pdfConverter = new HtmlToPdfConverter(); pdfConverter.Size = PageSize.A4; pdfConverter.Margins = new PageMargins { Top = 15, Bottom = 15, Left = 10, Right = 10 }; // 直接返回生成的PDF字节流 return pdfConverter.GeneratePdf(processedHtml); }
注意事项
opacity参数可在0.1-0.3区间调整,符合常规水印的透明度要求- 必须使用
position:fixed属性,才能保证每一页都会渲染水印层 - 如果是网络地址的水印图片,可直接填写到img的src属性,无需转base64
实现方式2:已生成PDF后叠加水印
如果是对已有的PDF文件添加水印,可以用PdfMerger直接在PDF页面上绘制水印:
using NReco.PdfRenderer; using System.Drawing; public void AddWatermarkToPdf(string sourcePdfPath, string outputPdfPath, string watermarkImagePath) { var watermarkImg = Image.FromFile(watermarkImagePath); var pdfMerger = new PdfMerger(); // 遍历所有页面叠加水印 pdfMerger.DrawOnPages(sourcePdfPath, outputPdfPath, (graphics, pageSize, pageIndex) => { // 可自定义水印的大小、位置、透明度 graphics.DrawImage(watermarkImg, new Rectangle(0, 0, (int)pageSize.Width, (int)pageSize.Height)); }); }
常见问题排查
- 水印被内容遮挡:检查水印层的z-index是否设置为负数,或者调整页面内容的z-index均低于水印层即可
- 水印仅在第一页显示:确认水印层用的是
position:fixed而非position:absolute - NReco免费版本会在PDF首页生成小版权标记,商业使用需要购买官方授权
内容的提问来源于stack exchange,提问作者Manish - Etymon
相关产品推荐
相关产品推荐

