跳至頁尾內容
移民指南

如何在 C# 中將 Playwright 移轉到 IronPDF

從 劇作家 for .NET 遷移到 IronPDF 會將您的 PDF 產生工作流程從以測試為中心的瀏覽器自動化工具轉變為專用的 PDF 庫。 本指南提供了一條完整的、循序漸進的遷移路徑,消除了複雜的非同步模式、瀏覽器生命週期管理和 400MB 以上的瀏覽器下載,同時提供了更好的效能和專業的 PDF 功能。

為什麼要從 劇作家 遷移到 IronPDF

了解 .NET 的 Playwright

Playwright for .NET 是微軟瀏覽器自動化工具系列的一部分; 它的結構圍繞著提供跨 Chromium、Firefox 和 WebKit 的全面測試功能而建構。 該庫採用"測試優先"的設計理念,這意味著它的主要關注點是涉及基於瀏覽器的測試場景。 雖然 劇作家 支援產生 PDF 文件,但此功能更像是一種補充功能,並不像專用 PDF 工具那樣提供精細的配置。

Playwright for .NET 主要是一個瀏覽器自動化和測試框架,PDF 生成只是其輔助功能。 與 PuppeteerSharp 類似,Playwright 使用瀏覽器的"列印到 PDF"功能產生 PDF 檔案——相當於按下 Ctrl+P。這樣生成的輸出檔案針對紙張進行了最佳化,可以直接用於列印,這與螢幕渲染有所不同。

測試框架問題

Playwright 的設計初衷是用於端對端測試,而不是產生文件。 這會為使用 PDF 文件帶來根本性問題:

  1. 首次使用前需下載 400MB 以上的瀏覽器檔案。 劇作家 的預設配置涉及下載多個瀏覽器,這對於資源受限的環境來說可能是一個需要考慮的問題。

  2. 具有瀏覽器上下文和頁面管理的複雜非同步模式。 開發人員必須熟悉瀏覽器上下文和頁面管理,以及正確的資源釋放方法。

3.測試優先架構不針對文件產生進行最佳化。

4.列印到 PDF 的限制與 Ctrl+P 瀏覽器列印相同。 佈局可能會重新排版,背景預設可能會省略,並且輸出會分頁以便列印。

5.不支援 PDF/A 或 PDF/UA無障礙存取。 劇作家無法製作符合 PDF/A(存檔)或 PDF/UA(無障礙)標準的文件。 對於第 508 條款、歐盟無障礙指令或長期存檔要求,您需要一個專門的 PDF 庫。

  1. 需要完整瀏覽器執行個體的資源密集型操作

劇作家 與 IronPDF 效能比較

指標劇作家IronPDF
主要目的瀏覽器測試PDF生成
瀏覽器下載400MB+(Chromium、Firefox、WebKit)內建優化引擎
首次渲染(冷啟動)4.5秒2.8秒
後續渲染3.8-4.1秒0.8-1.2秒
每次轉換的記憶體280-420MB80-120MB
API複雜度非同步瀏覽器/上下文/頁面生命週期同步單句
初始化playwright install + CreateAsync + LaunchAsyncnew ChromePdfRenderer()
PDF/A 支持無法使用全力支持
PDF/UA 無障礙訪問無法使用全力支持
數位簽名無法使用全力支持
PDF編輯無法使用合併、拆分、蓋章、編輯
專業支援社群商業服務水準協議

IronPDF 的設計初衷是專注於 PDF 生成。 與以測試為中心的 劇作家 不同,IronPDF 提供了各種以文件為中心的 API 功能。 它依賴一個經過最佳化的 Chromium 實例,注重效率,並提供同步和非同步操作。 這為需要 PDF 功能的開發人員簡化了思維模型和工作流程。

對於計劃在 2025 年和 2026 年採用 .NET 10 和 C# 14 的團隊,IronPDF 提供了一個專門構建的 PDF 解決方案,該方案消除了瀏覽器自動化開銷,同時提供了更好的性能和專業的文檔功能。


開始之前

先決條件

  1. .NET 環境: .NET Framework 4.6.2+ 或 .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet 存取權限:能夠安裝 NuGet 套件
  3. IronPDF 許可證:請從ironpdf.com取得您的許可證密鑰。

NuGet 套件變更

# Remove Playwright
dotnet remove package Microsoft.Playwright

# Remove browser binaries (reclaim ~400MB disk space)
# Delete the .playwright folder in your project or user directory

# Add IronPDF
dotnet add package IronPdf
# Remove Playwright
dotnet remove package Microsoft.Playwright

# Remove browser binaries (reclaim ~400MB disk space)
# Delete the .playwright folder in your project or user directory

# Add IronPDF
dotnet add package IronPdf
SHELL

使用 IronPDF 無需playwright install ,渲染引擎會自動捆綁。

許可證配置

// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

完整 API 參考

命名空間變更

// Before: Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
// Before: Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
$vbLabelText   $csharpLabel

核心 API 映射

劇作家 APIIronPDF API筆記
Playwright.CreateAsync()new ChromePdfRenderer()無需異步
playwright.Chromium.LaunchAsync()不需要無瀏覽器管理
browser.NewPageAsync()不需要無頁面上下文
page.GotoAsync(url)renderer.RenderUrlAsPdf(url)直接 URL 渲染
page.SetContentAsync(html) + page.PdfAsync()renderer.RenderHtmlAsPdf(html)單方法
page.CloseAsync()不需要自動清理
browser.CloseAsync()不需要自動清理
PagePdfOptions.FormatRenderingOptions.PaperSize紙張尺寸
PagePdfOptions.MarginRenderingOptions.MarginTop/Bottom/Left/Right個人利潤
PagePdfOptions.DisplayHeaderFooterRenderingOptions.TextHeader / TextFooter頁首/頁尾
PagePdfOptions.HeaderTemplateRenderingOptions.HtmlHeaderHTML 頭部
PagePdfOptions.FooterTemplateRenderingOptions.HtmlFooterHTML頁腳
<span> class="pageNumber">{page}頁碼佔位符

程式碼遷移範例

範例 1:HTML 字串到 PDF 的轉換

之前(劇作家):

// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        string html = "<h1>Hello World</h1><p>This is a test PDF.</p>";
        await page.SetContentAsync(html);
        await page.PdfAsync(new PagePdfOptions { Path = "output.pdf" });

        await browser.CloseAsync();
    }
}
// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        string html = "<h1>Hello World</h1><p>This is a test PDF.</p>";
        await page.SetContentAsync(html);
        await page.PdfAsync(new PagePdfOptions { Path = "output.pdf" });

        await browser.CloseAsync();
    }
}
$vbLabelText   $csharpLabel

(IronPDF 之後):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        string html = "<h1>Hello World</h1><p>This is a test PDF.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        string html = "<h1>Hello World</h1><p>This is a test PDF.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

這個例子展示了架構上的根本差異。 劇作家 需要五個非同步操作: Playwright.CreateAsync()Chromium.LaunchAsync()NewPageAsync()SetContentAsync()PdfAsync() ,以及使用CloseAsync()進行明確瀏覽器清理。

IronPDF 消除了所有這些複雜性:建立一個ChromePdfRenderer ,呼叫RenderHtmlAsPdf() ,然後SaveAs() 。 沒有非同步模式,沒有瀏覽器生命週期,沒有清理程式碼。 IronPDF 的方法提供了更簡潔的語法和與現代 .NET 應用程式更好的整合。 請參閱HTML 轉 PDF 文件以取得完整範例。

範例 2:URL 轉 PDF

之前(劇作家):

// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        await page.GotoAsync("https://www.example.com");
        await page.PdfAsync(new PagePdfOptions 
        { 
            Path = "webpage.pdf",
            Format = "A4"
        });

        await browser.CloseAsync();
    }
}
// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        await page.GotoAsync("https://www.example.com");
        await page.PdfAsync(new PagePdfOptions 
        { 
            Path = "webpage.pdf",
            Format = "A4"
        });

        await browser.CloseAsync();
    }
}
$vbLabelText   $csharpLabel

(IronPDF 之後):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
$vbLabelText   $csharpLabel

Playwright 使用GotoAsync()導覽至 URL,然後使用PdfAsync() 。 IronPDF 提供了一個RenderUrlAsPdf()方法,該方法可在一個呼叫中處理導覽和 PDF 產生。 請注意,Playwright 需要在PagePdfOptions中指定Format ,而 IronPDF 使用RenderingOptions.PaperSize進行紙張大小配置。 了解更多信息,請閱讀我們的教程

範例 3:自訂頁面尺寸和邊距

之前(劇作家):

// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var playwright = await Playwright.CreateAsync();
        await using var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();
        await page.SetContentAsync("<h1>Custom PDF</h1><p>Letter size with margins</p>");
        await page.PdfAsync(new PagePdfOptions 
        { 
            Path = "custom.pdf",
            Format = "Letter",
            Margin = new Margin { Top = "1in", Bottom = "1in", Left = "0.5in", Right = "0.5in" }
        });
    }
}
// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var playwright = await Playwright.CreateAsync();
        await using var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();
        await page.SetContentAsync("<h1>Custom PDF</h1><p>Letter size with margins</p>");
        await page.PdfAsync(new PagePdfOptions 
        { 
            Path = "custom.pdf",
            Format = "Letter",
            Margin = new Margin { Top = "1in", Bottom = "1in", Left = "0.5in", Right = "0.5in" }
        });
    }
}
$vbLabelText   $csharpLabel

(IronPDF 之後):

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.MarginTop = 25;
        renderer.RenderingOptions.MarginBottom = 25;
        renderer.RenderingOptions.MarginLeft = 12;
        renderer.RenderingOptions.MarginRight = 12;
        var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Letter size with margins</p>");
        pdf.SaveAs("custom.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.MarginTop = 25;
        renderer.RenderingOptions.MarginBottom = 25;
        renderer.RenderingOptions.MarginLeft = 12;
        renderer.RenderingOptions.MarginRight = 12;
        var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Letter size with margins</p>");
        pdf.SaveAs("custom.pdf");
    }
}
$vbLabelText   $csharpLabel

Playwright 使用基於字串的邊距值( &quot;1in&quot;&quot;0.5in&quot; ),而 IronPDF 則使用數值毫米值。 換算關係為:1 英吋 = 25.4 毫米,所以&quot;1in&quot;變成25&quot;0.5in&quot;變成大約12 。 劇作家Format = &quot;Letter&quot;對應到 IronPDF 的PaperSize = PdfPaperSize.Letter

範例 4:頁首、頁尾和自訂設置

之前(劇作家):

// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        string html = "<h1>Custom PDF</h1><p>With margins and headers.</p>";
        await page.SetContentAsync(html);

        await page.PdfAsync(new PagePdfOptions
        {
            Path = "custom.pdf",
            Format = "A4",
            Margin = new Margin { Top = "1cm", Bottom = "1cm", Left = "1cm", Right = "1cm" },
            DisplayHeaderFooter = true,
            HeaderTemplate = "<div style='font-size:10px; text-align:center;'>Header</div>",
            FooterTemplate = "<div style='font-size:10px; text-align:center;'>Page <span class='pageNumber'></span></div>"
        });

        await browser.CloseAsync();
    }
}
// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        string html = "<h1>Custom PDF</h1><p>With margins and headers.</p>";
        await page.SetContentAsync(html);

        await page.PdfAsync(new PagePdfOptions
        {
            Path = "custom.pdf",
            Format = "A4",
            Margin = new Margin { Top = "1cm", Bottom = "1cm", Left = "1cm", Right = "1cm" },
            DisplayHeaderFooter = true,
            HeaderTemplate = "<div style='font-size:10px; text-align:center;'>Header</div>",
            FooterTemplate = "<div style='font-size:10px; text-align:center;'>Page <span class='pageNumber'></span></div>"
        });

        await browser.CloseAsync();
    }
}
$vbLabelText   $csharpLabel

(IronPDF 之後):

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.TextHeader.CenterText = "Header";
        renderer.RenderingOptions.TextFooter.CenterText = "Page {page}";

        string html = "<h1>Custom PDF</h1><p>With margins and headers.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("custom.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.TextHeader.CenterText = "Header";
        renderer.RenderingOptions.TextFooter.CenterText = "Page {page}";

        string html = "<h1>Custom PDF</h1><p>With margins and headers.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("custom.pdf");
    }
}
$vbLabelText   $csharpLabel

此範例展示了頁首/頁尾佔位符語法的差異。 劇作家 使用基於 HTML 類別的佔位符(<span> class="pageNumber"></span> ),而 IronPDF 則使用花括號佔位符( {page} )。 請注意,Playwright 需要DisplayHeaderFooter = true才能啟用頁首/頁腳,而 IronPDF 會在您設定頁首/頁尾內容時自動啟用它們。


關鍵遷移說明

異步到同步轉換

Playwright 需全程使用 async/await; IronPDF 支援同步操作:

// Playwright: Async required
public async Task<byte[]> GeneratePdfAsync(string html)
{
    using var playwright = await Playwright.CreateAsync();
    await using var browser = await playwright.Chromium.LaunchAsync();
    var page = await browser.NewPageAsync();
    await page.SetContentAsync(html);
    return await page.PdfAsync();
}

// IronPDF: Sync is simpler
public byte[] GeneratePdf(string html)
{
    var renderer = new ChromePdfRenderer();
    return renderer.RenderHtmlAsPdf(html).BinaryData;
}
// Playwright: Async required
public async Task<byte[]> GeneratePdfAsync(string html)
{
    using var playwright = await Playwright.CreateAsync();
    await using var browser = await playwright.Chromium.LaunchAsync();
    var page = await browser.NewPageAsync();
    await page.SetContentAsync(html);
    return await page.PdfAsync();
}

// IronPDF: Sync is simpler
public byte[] GeneratePdf(string html)
{
    var renderer = new ChromePdfRenderer();
    return renderer.RenderHtmlAsPdf(html).BinaryData;
}
$vbLabelText   $csharpLabel

邊際單位轉換

劇作家運用弦樂單元; IronPDF 使用數值毫米:

劇作家IronPDF(毫米)
"1in"25
"0.5in"12
"1cm"10

頁首/頁尾佔位符轉換

劇作家班IronPDF佔位符
<span> class="pageNumber">{page}
<span> class="totalPages">{total-pages}
<span> class="date">{date}
<span> class="title">{html-title}

瀏覽器生命週期消除

移除所有瀏覽器管理程式碼:

// Playwright: Explicit cleanup required
await page.CloseAsync();
await browser.CloseAsync();
playwright.Dispose();

// IronPDF: No disposal needed - just use the renderer
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// Playwright: Explicit cleanup required
await page.CloseAsync();
await browser.CloseAsync();
playwright.Dispose();

// IronPDF: No disposal needed - just use the renderer
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
$vbLabelText   $csharpLabel

遷移後的新功能

移轉到 IronPDF 後,您將獲得 劇作家 無法提供的功能:

PDF合併

var pdf1 = renderer.RenderHtmlAsPdf(html1);
var pdf2 = renderer.RenderHtmlAsPdf(html2);
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
var pdf1 = renderer.RenderHtmlAsPdf(html1);
var pdf2 = renderer.RenderHtmlAsPdf(html2);
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
$vbLabelText   $csharpLabel

水印

pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>");
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>");
$vbLabelText   $csharpLabel

密碼保護

pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "readonly";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "readonly";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
$vbLabelText   $csharpLabel

數位簽名

var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);
var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);
$vbLabelText   $csharpLabel

PDF/A 合規性

pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
$vbLabelText   $csharpLabel

遷移清單

遷移前

  • 識別所有 劇作家 PDF 產生程式碼
  • 文檔邊距值(將英吋/公分轉換為毫米)
  • 注意頁首/頁尾佔位符語法以進行轉換
  • ironpdf.com取得 IronPDF 許可證金鑰

軟體包變更

  • 刪除Microsoft.Playwright NuGet 套件
  • 刪除.playwright資料夾回收約 400MB 磁碟空間 安裝IronPdf NuGet 套件: dotnet add package IronPdf

程式碼更改

  • 更新命名空間匯入
  • 使用ChromePdfRenderer取代非同步瀏覽器生命週期
  • page.SetContentAsync() + page.PdfAsync()轉換為RenderHtmlAsPdf()
  • page.GotoAsync() + page.PdfAsync()轉換為RenderUrlAsPdf()
  • 將邊距字串轉換為毫米值
  • 轉換頁首/頁尾佔位符語法
  • 刪除所有瀏覽器/頁面銷毀程式碼
  • 在應用程式啟動時新增許可證初始化

移民後

  • PDF 輸出的視覺比較
  • 驗證頁首/頁尾的顯示是否正確,並顯示頁碼
  • 測試頁邊距和頁面尺寸的準確性
  • 根據需要新增功能(安全性、浮水印、合併)

柯蒂斯·週
技術撰稿人

Curtis Chau擁有卡爾頓大學電腦科學學士學位,專長於前端開發,精通Node.js、TypeScript、JavaScript和React。他熱衷於打造直覺美觀的使用者介面,喜歡使用現代框架,並擅長撰寫結構清晰、視覺效果出色的使用者手冊。

除了開發工作之外,柯蒂斯對物聯網 (IoT) 也抱有濃厚的興趣,致力於探索硬體和軟體整合的創新方法。閒暇時,他喜歡玩遊戲和製作 Discord 機器人,將他對科技的熱愛與創造力結合。