.NET Core 2.1使用iTextSharp将含CSS、图标的HTML转PDF报错排查
问题描述
尝试使用iTextSharp将包含CSS样式、图标资源的HTML转换为PDF文件时功能无法正常运行,当前运行环境为.NET Core 2.1,功能实现代码如下:
public static void pdf() { byte[] pdf; // result will be here var cssText = File.ReadAllText(@"./css/main.css"); var html = File.ReadAllText(@"./index.html"); using (var memoryStream = new MemoryStream()) { var document = new Document(PageSize.A4, 50, 50, 60, 60); var writer = PdfWriter.GetInstance(document, memoryStream); document.Open(); using (var cssMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(cssText))) { using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(html))) { XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, htmlMemoryStream, cssMemoryStream); } } document.Close(); pdf = memoryStream.ToArray(); } File.WriteAllBytes(@"./2.pdf", pdf); }
运行代码时抛出如下错误:
Method not found: 'System.Runtime.Remoting.ObjectHandle System.Activator.CreateInstance(System.String, System.String)'.
错误根本原因
当前引用的iTextSharp(即iText 5.x系列版本)及配套的XMLWorker组件是基于.NET Framework开发的,依赖.NET Framework独有的System.Runtime.Remoting命名空间下的API。.NET Core从首个版本开始就完全移除了Remoting相关实现,不存在Activator.CreateInstance(string, string)这个带程序集名、类型名参数的重载方法,运行时找不到对应方法就会抛出该错误。
即使通过自定义垫片绕过这个方法缺失的问题,旧版iTextSharp和XMLWorker在.NET Core环境下还会存在CSS解析异常、资源路径解析不兼容、字体加载失败等一系列问题,完全无法稳定支持带图标、自定义样式的HTML转PDF需求。
解决方案
- 移除项目中引用的旧版iTextSharp、XMLWorker相关包,替换为官方适配.NET Standard/.NET Core的iText 7系列包,核心需要安装
itext7和itext7.pdfhtml两个包,这两个包原生支持.NET Core 2.1及以上版本,不存在Remoting依赖问题,对CSS3、图标/字体等外部资源的支持度远高于旧版XMLWorker。 - 替换包后可参考如下实现代码,逻辑和原有需求对齐:
using iText.Kernel.Geom; using iText.Kernel.Pdf; using iText.Html2pdf; using iText.Layout; using System.IO; public static void Pdf() { byte[] pdf; var html = File.ReadAllText(@"./index.html"); using (var memoryStream = new MemoryStream()) { // 初始化PDF写入器、文档,保持原A4规格、50/50/60/60页边距配置 var pdfWriter = new PdfWriter(memoryStream); var pdfDoc = new PdfDocument(pdfWriter); pdfDoc.SetDefaultPageSize(PageSize.A4); // 配置转换参数,设置资源根目录用于自动加载CSS、图标、字体等文件 ConverterProperties props = new ConverterProperties(); props.SetBaseUri("./"); // 执行HTML转PDF HtmlConverter.ConvertToPdf(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(html)), pdfWriter, props); pdfDoc.Close(); pdf = memoryStream.ToArray(); } File.WriteAllBytes(@"./2.pdf", pdf); }
- 如果需要加载自定义CSS、图标字体等资源,只需要通过
SetBaseUri()设置资源所在的根目录即可,组件会自动按照HTML中的相对路径加载对应资源,不需要手动读取CSS流传入,兼容性更好。 - 如果因为授权、历史代码兼容等原因必须使用iText 5.x版本的API,只能将项目目标框架切换为.NET Framework 4.x,没有可行方案能让旧版iTextSharp在.NET Core环境下稳定运行。
内容的提问来源于stack exchange,提问作者mohit
相关产品推荐
相关产品推荐

