c# - iTextSharp XMLParser.Parse 反复抛出并吞下异常
问题描述
我有一个函数用于尝试为 iTextSharp 提供一些 HTML 并从中生成 PDF。这个函数成功地生成了带有 CSS 样式的 PDF,但它的运行速度不足以满足我们的要求。
我已经注意到一个特别需要很长时间才能执行的区域是调用XMLParser.Parse
,我看到一个 8 页的文档需要超过 14 秒才能完成,该文档显示的只是一个以图标为标题的数据表。在执行此方法期间,我注意到(在输出窗口中)三个异常被 iTextSharp 或 iTextSharp 调用的代码抛出(并且可能被捕获)。这些例外是:
- mscorlib.dll 中的“System.Collections.Generic.KeyNotFoundException”
- itextsharp.xmlworker.dll 中的“iTextSharp.tool.xml.exceptions.NoDataException”
- mscorlib.dll 中的“System.ArgumentException”
在 Parse 方法完成执行之前,这三个异常会重复(尽管不一定按此顺序)。
虽然我意识到我不需要自己处理这些异常,但我之所以提到它们,是因为我正在尝试提高此方法的性能并了解捕获异常可能是一项昂贵的操作。我正在寻找的是引发这些异常的原因是什么,如果它取决于我传入的坏数据,那么坏的数据是什么?
这是目前的 HTML 到 PDF 功能。请注意,我已经XMLWorkerFontProvider.DONTLOOKFORFONTS
按照 itext_so 手册的建议尝试过使用,但这样做并没有带来任何性能提升。我还注意到一次NullReferenceException
被抛出和吞下PdfWriter.GetInstance
;我想知道这是否也与Parse
方法中抛出的异常有关。
public static byte[] GeneratePdfFromHtml(string html, Action<PdfWriter, Document> pdfSettings = null, string additionalFooterText = null)
{
var tagProcessor = (DefaultTagProcessorFactory)Tags.GetHtmlTagProcessorFactory();
tagProcessor.RemoveProcessor(HTML.Tag.IMG);
tagProcessor.AddProcessor(HTML.Tag.IMG, new CustomProcessorImageTag());
using (var workStream = new MemoryStream())
using (var document = new Document())
//NOTE: The NullReferenceException is thrown via this call.
using (PdfWriter writer = PdfWriter.GetInstance(document, workStream))
{
PdfEventHelper pdfEventHelper = new PdfEventHelper(additionalFooterText);
writer.PageEvent = pdfEventHelper;
writer.CloseStream = false;
pdfSettings?.Invoke(writer, document);
document.Open();
var xmlWorkerFontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
//Not noticably faster without this font directory registration.
xmlWorkerFontProvider.RegisterDirectory("~/Content/fonts", false);
//TODO: If further performance is needed then this line is the next slowest (.43ms).
var htmlContext = new HtmlPipelineContext(new CssAppliersImpl(xmlWorkerFontProvider));
htmlContext.SetTagFactory(tagProcessor);
Func<string, string> mapPath = HttpContext.Current.Server.MapPath;
var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
foreach (var cssFileName
in new[]
{
"bootstrap.min.css",
"Pdf.css",
"Rdp.css"
})
cssResolver.AddCssFile(mapPath($"~/Content/{cssFileName}"), true);
using (var reader = new StringReader(html))
{
new XMLParser(
new XMLWorker(
new CssResolverPipeline(
cssResolver,
new HtmlPipeline(
htmlContext,
new PdfWriterPipeline(
document,
writer))),
true))
//TODO: Speed up this line - this is the slowest line in the method by far.
//NOTE: This throws a series of ArgumentExceptions, NoDataExceptions and KeyNotFoundExceptions.
.Parse(reader);
document.Close();
return workStream.ToArray();
}
}
}
解决方案
推荐阅读
- python - 如何使用正则表达式用基本字母替换变音符号?
- jupyter-notebook - 如何在 jupyter lab 中正确查看 markdown 文件?
- xcode - 第三方 Pod 的 LFS 带宽超过其数据配额 (SendBirdWebRTC)
- c - MADV_REMOVE 会导致 TLB 击落吗?
- ios - 私人消费 NSDictionary 属性
- json - 使用 List.Generate 的 Power BI API
- javascript - 想要根据 webpack 构建模式使用 2 个不同的 .js 文件中的任何一个
- javascript - 如何在实时视频流中连续捕获和保存 .jpg 图像帧?
- reactjs - 关闭模式后屏幕上的多选文本输入
- python - 将图像路径添加到 .txt 文件