我正在使用iTextSharp和xmlworker将ASP.NET Core 2.1中的视图中的HTML转换为PDF。
我尝试了许多在网上找到的代码片段,但都会生成一个异常:
The document has no pages.
这是我的当前代码:
public static byte[] ToPdf(string html)
{
byte[] output;
using (var document = new Document())
{
using (var workStream = new MemoryStream())
{
PdfWriter writer = PdfWriter.GetInstance(document, workStream);
writer.CloseStream = false;
document.Open();
using (var reader = new StringReader(html))
{
XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader);
document.Close();
output = workStream.ToArray();
}
}
}
return output;
}
更新1
感谢@Bruno Lowagie的建议,我升级到了iText7和pdfHTML,但是我找不到太多关于它们的教程。
我尝试了这段代码:
public static byte[] ToPdf(string html)
{
html = "<html><head><title>Extremely Basic Title</title></head><body>Extremely Basic Content</body></html>";
byte[] output;
using (var workStream = new MemoryStream())
using (var pdfWriter = new PdfWriter(workStream))
{
using (var document = HtmlConverter.ConvertToDocument(html, pdfWriter))
{
//Passes the document to a delegated function to perform some content, margin or page size manipulation
//pdfModifier(document);
}
//Returns the written-to MemoryStream containing the PDF.
return workStream.ToArray();
}
}
但是当我调用HtmlConverter.ConvertToDocument(html, pdfWriter)
时,我遇到了
System.NullReferenceException
我错过了什么吗?
更新2
我尝试使用源代码进行调试。
这是堆栈跟踪
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=itext.io
StackTrace: at iText.IO.Font.FontCache..cctor() in S:\Progetti\*****\itext7-dotnet-develop\itext\itext.io\itext\io\font\FontCache.cs:line 76
这是生成异常的代码:
static FontCache()
{
try
{
LoadRegistry();
foreach (String font in registryNames.Get(FONTS_PROP))
{
allCidFonts.Put(font, ReadFontProperties(font));
}
}
catch (Exception) { }
}
registryNames count = 0 and .Get(FONTS_PROP) throws the exception
更新3
问题与某种缓存相关,我无法确定是什么缓存,但是根据代码可以看出异常是在尝试从缓存中加载字体时生成的。
在一个新项目上尝试相同的代码后,我意识到这一点。
所以我清理了解决方案,删除了 bin、obj、.vs 文件夹,终止了 IIS Express,卸载并重新安装了所有 NuGet 包,然后再次运行,奇迹般地它工作了。
然后我只需要对代码进行一处修复:
我使用 HtmlConverter.ConvertToPdf
代替 HtmlConverter.ConvertToDocument
来生成完整的 PDF。
以下是完整的代码:
public static byte[] ToPdf(string html)
{
using (var workStream = new MemoryStream())
{
using (var pdfWriter = new PdfWriter(workStream))
{
HtmlConverter.ConvertToPdf(html, pdfWriter);
return workStream.ToArray();
}
}
}