IRONSOFTWAREHOME
PDF 工具

PDF 与 PDF/A(比较及使用方法)

Curtis Chau
Curtis Chau
Updated: 2026年6月20日

iText "文档没有页面"错误会在XMLWorker无法解析HTML内容时出现,但IronPDF的基于Chrome的渲染器通过像浏览器一样精确地处理HTML,解决了这个问题,提供了可靠的PDF生成而没有解析异常。

在.NET应用程序中将HTML转换为PDF是一个常见需求,但使用iText的开发者经常会遇到"文档没有页面"的错误。 当 PDF 文档生成过程失败时,会出现此错误,导致开发人员需要寻找解决方案。 本分析探讨了发生这种情况的原因以及如何使用IronPDF 的 HTML 转 PDF 功能有效地解决它。

什么原因导致 "文档无页 "错误?

"文档没有页面"异常出现在iText的解析器无法将HTML内容处理为有效的PDF文档时。 此错误通常发生在文档关闭操作期间, Stack Overflow 上有很多关于此问题的讨论帖对此进行了详细描述。 了解根本原因有助于开发人员根据自身需求选择合适的 PDF 库。

此错误出现是因为XMLWorker——iText的HTML解析组件——在遇到无法处理的HTML结构时无声失败。 它不会在解析过程中引发异常,而是生成一个空文档。 当文档关闭时,iText检测没有写入内容并抛出"文档没有页面"异常。 这种静默故障模式使得调试特别令人沮丧,因为堆栈跟踪指向的是关闭操作,而不是实际的解析失败。

static void Main(string[] args)
{
    Document pdfDoc = new Document(PageSize.A4);
    FileStream stream = new FileStream("output.pdf", FileMode.Create);
    PdfWriter writer = PdfWriter.GetInstance(pdfDoc, stream);
    pdfDoc.Open();
    // HTML parsing fails silently -- no exception here
    var sr = new StringReader("<div>Complex HTML</div>");
    XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
    pdfDoc.Close(); // Exception: The document has no pages
    Console.WriteLine("Error: Document has no pages");
}

发生此错误时,控制台输出显示什么?

Microsoft Visual Studio调试控制台显示

这段代码尝试从 HTML 创建 PDF 文件,但由于 XMLWorker 无法成功解析 HTML 内容而遇到异常。 写入操作已完成,但文档中未添加任何内容,导致生成一个空文件。这种解析失败是开发人员在 ASP.NET 应用程序中进行 HTML 转 PDF 转换时最常遇到的问题之一。 当处理自定义 CSS 样式或 JavaScript 渲染的内容时,问题会变得更加复杂。

为什么替换库也会面临同样的问题?

虽然 XMLWorker 取代了已废弃的 HTMLWorker,但它在处理某些 HTML 结构时仍会遇到同样的问题。 问题依然存在,因为 XMLWorker 有严格的解析要求,正如iText 官方论坛中记录的那样。 此限制会影响尝试实现像素级精确的 HTML 到 PDF 转换或在现代 Web 应用程序中使用响应式 CSS 布局的开发人员。

常见的解决方法是在解析 HTML 之前,先在文档中预先填充一个空段落。 这样可以防止出现"无页面"异常,确保文档关闭时至少存在一个内容元素:

public static void CreatePDF(string html, string path)
{
    using (var fs = new FileStream(path, FileMode.Create))
    {
        var document = new Document();
        var writer = PdfWriter.GetInstance(document, fs);
        document.Open();
        document.Add(new Paragraph("")); // Workaround to avoid error
        var phrase = new Phrase("Draft version", FontFactory.GetFont("Arial", 8));
        document.Add(phrase);
        using (var sr = new StringReader(html))
        {
            XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, sr);
        }
        document.Close();
    }
}

使用此方法后,PDF 输出结果会是什么样子?

成功生成的PDF显示

为什么复杂的HTML元素仍然无法渲染?

添加一个空段落可以防止立即出现错误,但包含表格元素、图像或自定义字体的复杂 HTML 经常无法正确渲染。 生成的PDF文档中可能缺少内容或格式错误。 开发人员在处理带有嵌入式样式、超链接元素或特定宽度属性的 HTML 时会遇到同样的问题。 空引用和缺失元素渲染会引发其他问题,需要进一步解决。

XMLWorker被设计用来处理HTML 4的子集和基础CSS 2。现代网页通常使用超出这个范围的特性:CSS Grid、Flexbox、CSS变量、calc()表达式、SVG图形和JavaScript驱动的渲染。 这些情况中的任何一个都可能触发"无页面"错误或静默地产生损坏的输出——而且没有任何描述性的错误消息来指导修复。

// Common XMLWorker limitations that require manual handling
public void ProcessComplexHTML(string htmlContent)
{
    // CSS flexbox -- not supported by XMLWorker
    if (htmlContent.Contains("display: flex"))
        throw new NotSupportedException("Flexbox layout not supported");

    // JavaScript content -- silently ignored
    if (htmlContent.Contains("<script>"))
        Console.WriteLine("Warning: JavaScript will be ignored");

    // 自定义字体 -- require manual embedding
    if (htmlContent.Contains("@font-face"))
        Console.WriteLine("Warning: Web fonts need manual setup");
}
C#

如何转换现代 HTML 而不出现同样的错误?

这个真实案例演示了如何将带有样式的发票从 HTML 转换为 PDF。 该示例包含一些经常导致问题的常见元素:内联 CSS、媒体查询、表格布局和超链接。 以下类型的结构会触发 XMLWorker 中的"无页面"错误:

<!-- Invoice HTML with modern styling -->
<!DOCTYPE html>
<html>
<head>
    <title>Invoice Sample</title>
    <style>
        .invoice-header {
            background-color: #f0f0f0;
            padding: 20px;
        }
        .invoice-table {
            margin-top: 20px;
        }
        @media print {
            .no-print { display: none; }
        }
    </style>
</head>
<body>
    <div style="font-family: Arial; width: 100%;">
        <div class="invoice-header">
            <h1 style="color: #2e6c80;">Invoice #12345</h1>
            <p>Date: <span id="date">2025-01-15</span></p>
        </div>
        <table class="invoice-table" style="width: 100%; border-collapse: collapse;">
            <thead>
                <tr>
                    <th style="border: 1px solid #ddd; padding: 8px;">Item</th>
                    <th style="border: 1px solid #ddd; padding: 8px;">Price</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 8px;">Service</td>
                    <td style="border: 1px solid #ddd; padding: 8px;">$100.00</td>
                </tr>
            </tbody>
        </table>
        <a href="https://example.com/terms" class="no-print">View Terms</a>
    </div>
</body>
</html>
HTML

当iText处理此发票模板时会发生什么?

基础 invoice PDF displaying Invoice #12345 with simple table formatting containing one service item for $100, demonstrating iText's limited CSS styling capabilities and basic table rendering when XMLWorker successfully processes simple HTML structures

当iText处理此发票模板时,输出通常会剥离CSS样式,背景色缺失,表格边框丢失。 @media print查询被忽略,任何网页字体引用都会导致无声解析失败。 如果 HTML 中包含 XMLWorker 无法识别的 CSS 属性,则整个块可能无法渲染——导致内容缺失,且在解析时不会抛出任何错误。

IronPDF 如何渲染同一张发票?

Professional invoice PDF #12345 rendered with IronPDF showing preserved CSS styling, properly formatted table with service item for $100, and functioning 'View Terms' hyperlink, demonstrating the Chrome rendering engine's superior HTML/CSS support compared to XMLWorker

为什么这些HTML元素在iText中会引发问题?

使用iText的XMLWorker时,此发票可能因表格样式、宽度属性或字体规格而失败。 当不支持这些元素时,通常会出现"文档没有页面"错误。 超链接和媒体查询引用也可能无法正确呈现。 在商业应用中实现数字签名或页码等高级 PDF 功能时,这些限制就显得至关重要了。

根据Mozilla 开发者网络关于 CSS 的文档,现代 CSS 包含数百个浏览器原生支持的属性和值。 XMLWorker 仅涵盖其中的一小部分,这就是为什么现实世界的 Web 内容经常触发解析失败的原因。

如何处理HTML到PDF的转换而不会出现解析错误?

IronPDF使用基于 Chrome 的渲染引擎,能够完全按照 HTML 在网页浏览器中的显示方式进行处理。 这种方法可以消除解析错误,并支持所有现代 HTML 和 CSS 功能。 您可以查阅ChromePdfRenderer API 参考文档,了解完整的配置选项列表。 Chrome 引擎支持 JavaScript 执行、Web 字体和响应式布局,而 XMLWorker 无法处理这些功能。

如何通过 NuGet 安装 IronPDF?

在编写任何代码之前,请先安装 IronPDF NuGet 包。 您可以通过 .NET CLI 执行此操作:

> dotnet add package IronPdf

或者从 Visual Studio 中的 NuGet 程序包管理器控制台:

PM > Install-Package IronPdf

一旦安装完成,您可以访问ChromePdfRenderer,它用单一可靠的调用替换了整个iText + XMLWorker管道。

如何使用 IronPDF 将 HTML 渲染成 PDF?

以下示例渲染了在iText中引发失败的相同发票HTML。 注意,这里没有变通方法,没有需要预置的空段落,也没有需要处理的无声失败:

using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Configure rendering options for production use
renderer.RenderingOptions.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;

string html = @"<div style='font-family: Arial; width: 100%;'>
    <h1 style='color: #2e6c80;'>Invoice #12345</h1>
    <table style='width: 100%; border-collapse: collapse;'>
        <tr>
            <th style='border: 1px solid #ddd; padding: 8px;'>Item</th>
            <th style='border: 1px solid #ddd; padding: 8px;'>Price</th>
        </tr>
        <tr>
            <td style='border: 1px solid #ddd; padding: 8px;'>Service</td>
            <td style='border: 1px solid #ddd; padding: 8px;'>$100.00</td>
        </tr>
    </table>
</div>";

PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("invoice.pdf");

IronPDF 的输出效果如何?

干净的专业发票PDF,显示发票 #12345,拥有格式正确的两列表格,包含项目和价格的标题,展示了IronPDF的可靠HTML表格渲染,无解析错误或格式问题

为什么这种方法可以消除解析错误?

该代码无一例外地成功创建了 PDF 文件。 该方法可自动处理复杂的 HTML 和 CSS,无需使用变通方法。 内容渲染像素完美,与浏览器预览相匹配。 IronPDF 还支持异步渲染、自定义边距和 PDF 压缩,以优化文件大小。

对于涉及JavaScript密集内容或单页面应用程序的场景,IronPDF的RenderDelay选项允许JavaScript在PDF被捕获之前执行——这是XMLWorker完全无法做到的。 以下示例以可用于生产环境的异步模式添加页眉、页脚和安全设置:

using IronPdf;
using Microsoft.Extensions.Logging;

// Production-ready PDF generation with IronPDF
public class PdfGenerator
{
    private readonly ChromePdfRenderer _renderer;
    private readonly ILogger<PdfGenerator> _logger;

    public PdfGenerator(ILogger<PdfGenerator> logger)
    {
        _logger = logger;
        _renderer = new ChromePdfRenderer();
        _renderer.RenderingOptions.Timeout = 60;
        _renderer.RenderingOptions.EnableJavaScript = true;
        _renderer.RenderingOptions.RenderDelay = 2000;
        _renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
        {
            Height = 25,
            HtmlFragment = "<div style='text-align: center;'>{page} of {total-pages}</div>"
        };
    }

    public async Task<PdfDocument> GenerateWithRetry(string html, int maxRetries = 3)
    {
        for (int i = 0; i < maxRetries; i++)
        {
            try
            {
                _logger.LogInformation("Generating PDF, attempt {Attempt}", i + 1);
                return await _renderer.RenderHtmlAsPdfAsync(html);
            }
            catch (Exception ex)
            {
                _logger.LogWarning("PDF generation failed: {Message}", ex.Message);
                if (i == maxRetries - 1) throw;
                await Task.Delay(1000 * (i + 1));
            }
        }
        throw new InvalidOperationException("PDF generation failed after retries");
    }
}

生成可靠 PDF 的最佳解决方案是什么?

比较这两个用于HTML转PDF转换的库时,功能上的差异会直接影响PDF的质量和部署可靠性:

功能比较:iText加XMLWorker与IronPDF
特征iText + XMLWorkerIronPDF
现代 HTML/CSS 支持有限(HTML 4,CSS 2)完整版(Chrome渲染引擎)
JavaScript 执行无是
错误处理常见的解析异常可靠渲染
复杂表经常失败全面支持
自定义字体需要手动嵌入自动处理
支持 SVG无是
异步渲染无是
Docker/Linux 支持数量有限完全原生支持
CSS媒体类型基础屏幕和印刷
调试工具数量有限Chrome DevTools 集成

如何从iText迁移到IronPDF?

对于遇到 "文档无页面 "错误的开发人员来说,迁移到 IronPDF 可提供直接的解决方案。 转换过程很简单,IronPDF 提供了完整的文档和代码示例。 以下对比图显示了复杂度的降低:

// Before (iTextSharp) -- error-prone approach requiring workarounds
public byte[] CreatePdfWithIText(string htmlContent)
{
    using var ms = new MemoryStream();
    var document = new Document();
    var writer = PdfWriter.GetInstance(document, ms);
    document.Open();

    // Must add empty paragraph to avoid "no pages" error
    document.Add(new Paragraph(""));

    try
    {
        using var sr = new StringReader(htmlContent);
        XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, sr);
    }
    catch (Exception ex)
    {
        document.Add(new Paragraph("Error: " + ex.Message));
    }

    document.Close();
    return ms.ToArray();
}

// After (IronPDF) -- reliable, no workarounds needed
public byte[] CreatePdfWithIron(string htmlContent)
{
    ChromePdfRenderer renderer = new ChromePdfRenderer();
    renderer.RenderingOptions.EnableJavaScript = true;
    renderer.RenderingOptions.RenderDelay = 500;

    PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
    return pdf.BinaryData;
}

IronPDF 的 API 有哪些方面对开发者更友好?

简化的 API 意味着需要维护的代码更少,而且无需调试解析错误。 IronPDF 还提供添加页眉和页脚、合并 PDF以及应用数字签名等功能,无需复杂的变通方法。 对于在Docker 环境中工作或部署到 Linux 服务器的团队而言,IronPDF 可在各个平台上提供一致的行为。

NuGet使用 NuGet 安装

PM > Install-Package IronPdf

Install IronPDF by running the command above in the NuGet Package Manager Console, or search for the package in the NuGet Package Manager.

立即开始免费试用,体验无误的HTML 转 PDF 转换。

下一步计划是什么?

"文档没有页面"错误源于iText的XMLWorker内置的基础解析限制。 虽然有一些变通方法——例如预先在文档中填充一个空段落——但它们并不能解决复杂的 HTML 处理这一根本问题。 IronPDF 基于 Chrome 的渲染提供了一种可靠的解决方案,可以处理现代 Web 内容而不会出现解析异常。

对于需要从 HTML 生成一致 PDF 的生产应用程序,IronPDF 可消除调试解析器错误的挫折感,并提供专业的结果。 该引擎负责处理所有 HTML 元素、CSS 样式和 JavaScript,确保文档每次都能正确渲染。无论您是创建发票、报告,还是任何包含文本、表格和图像的文档,IronPDF 都能提供您所需的解决方案。

为了继续推进,建议采取以下后续步骤:

请注意: iText和XMLWorker是其各自所有者的注册商标。 本网站与iText或XMLWorker无任何关联、认可或赞助关系。 所有产品名称、徽标和品牌均为各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。
Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

...
阅读更多

相关文章

Key in blue circle

立即获取免费的 30 天试用版密钥。

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

OR
bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
预约您的免费现场演示
Booking Badge

深受全球数百万工程师信赖

Iron Software 的客户徽标
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥。
无需信用卡或创建账户
C# 用于 PDF 的 NuGet 库
通过 NuGet 安装

版本: 2026.9

PM > Install-Package IronPdf
nuget.org/packages/IronPdf/
  1. 在解决方案资源管理器中,右键点击引用,管理 NuGet 包
  2. 选择浏览并搜索 “IronPDF”
  3. 选择包并安装
C# PDF DLL
下载 DLL

版本: 2026.9

或在此处下载 Windows 安装程序。

  1. 下载并解压 IronPDF 到您的解决方案目录中的 ~/Libs 之类的位置
  2. 在 Visual Studio 解决方案资源管理器中,右键点击引用。选择浏览,“IronPDF.dll”

$999 起