跳至頁尾內容
移民指南

如何在 C# 中將 Winnovative 遷移到 IronPDF

Winnovative 在 .NET PDF 生成領域一直享有盛譽,為 C# 應用程式提供 HTML 到 PDF 的轉換功能。 然而,該程式庫依賴 2016 年的 WebKit 引擎,這給現代 Web 開發帶來了重大挑戰。 當代 CSS 功能(如網格佈局)、現代 JavaScript 語法以及 Bootstrap 5 和 Tailwind CSS 等流行框架經常無法正確渲染,甚至根本無法渲染。

本指南提供了從 創新贏家 到 IronPDF 的完整遷移路徑,包括逐步說明、程式碼比較和實用範例,供正在評估此過渡的專業 .NET 開發人員參考。

為什麼要從 創新贏家 遷移?

Winnovative 依賴 2016 年的 WebKit 引擎,這給現代 Web 應用程式帶來了嚴重的問題:

不支援 CSS Grid: Bootstrap 5、Tailwind CSS 和現代佈局完全失效。 任何使用 CSS Grid 的頁面都將無法如預期渲染。

Flexbox實作有缺陷:與現代瀏覽器相比,渲染效果不一致。 開發人員經常花費數小時來調試僅在 創新贏家 中存在的佈局問題。

僅限 ES5 JavaScript:現代 ES6+ JavaScript 特性(箭頭函數、async/await、類別)會靜默失敗。 這意味著 React、Vue 和其他現代框架經常會產生損壞的輸出。

發展停滯:儘管"Winnovative"這個名字暗示著創新,但該產品近年來幾乎沒有更新。

字體渲染問題:網頁字體和自訂字體經常渲染不正確或根本無法渲染。

安全隱患: 2016 年的 WebKit 引擎缺乏多年的安全性修補程式和漏洞修復。

實際影響

現代 CSS 和 JavaScript 在 創新贏家 中根本無法正常運作:

<!-- This modern CSS breaks in 創新贏家 -->
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;">
  <div>Column 1</div>
  <div>Column 2</div>
  <div>Column 3</div>
</div>

<!-- Modern JavaScript fails silently -->
<script>
const items = data.map(item => item.name); // Arrow functions: FAIL
const result = await fetchData(); // Async/await: FAIL
class Report { } // Classes: FAIL
</script>
<!-- This modern CSS breaks in 創新贏家 -->
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;">
  <div>Column 1</div>
  <div>Column 2</div>
  <div>Column 3</div>
</div>

<!-- Modern JavaScript fails silently -->
<script>
const items = data.map(item => item.name); // Arrow functions: FAIL
const result = await fetchData(); // Async/await: FAIL
class Report { } // Classes: FAIL
</script>
HTML

IronPDF 與 Winnovative:功能對比

了解架構差異有助於技術決策者評估遷移投資:

方面創新贏家IronPDF
渲染引擎WebKit(2016)鉻(電流)
CSS Grid不支援。全力支持
Flexbox布吉全力支持
JavaScript僅限 ES5ES2024
Bootstrap 5破碎的全力支持
Tailwind CSS不支援。全力支持
React/Vue SSR有問題的完美運行
網頁字體不可靠全力支持
更新不頻繁每月
價格750-1600美元競爭的

快速入門:Winnovative 到 IronPDF 的遷移

透過這些基礎步驟,遷移工作可以立即開始。

步驟 1:替換 NuGet 套件

移除所有 創新贏家 軟體包:

# Remove Winnovative
dotnet remove package Winnovative.WebKitHtmlToPdf
dotnet remove package Winnovative.HtmlToPdf
dotnet remove package Winnovative.WebToPdfConverter
# Remove Winnovative
dotnet remove package Winnovative.WebKitHtmlToPdf
dotnet remove package Winnovative.HtmlToPdf
dotnet remove package Winnovative.WebToPdfConverter
SHELL

安裝 IronPDF:

# Install IronPDF
dotnet add package IronPdf
# Install IronPDF
dotnet add package IronPdf
SHELL

步驟 2:更新命名空間

將 創新贏家 命名空間替換為 IronPdf 命名空間:

// Before (Winnovative)
using Winnovative;
using Winnovative.WebKit;

// After (IronPDF)
using IronPdf;
// Before (Winnovative)
using Winnovative;
using Winnovative.WebKit;

// After (IronPDF)
using IronPdf;
$vbLabelText   $csharpLabel

步驟 3:初始化許可證

在應用程式啟動時新增許可證初始化:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

程式碼遷移範例

將 HTML 轉換為 PDF

最常見的用例展示了這些 .NET PDF 庫之間的 API 差異。

創新制勝之道:

// NuGet: Install-Package Winnovative.WebToPdfConverter
using Winnovative;
using System;

class Program
{
    static void Main()
    {
        // Create the HTML to PDF converter
        HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

        // Set license key
        htmlToPdfConverter.LicenseKey = "your-license-key";

        // Convert HTML string to PDF
        string htmlString = "<html><body><h1>Hello World</h1></body></html>";
        byte[] pdfBytes = htmlToPdfConverter.ConvertHtml(htmlString, "");

        // Save to file
        System.IO.File.WriteAllBytes("output.pdf", pdfBytes);

        Console.WriteLine("PDF created successfully");
    }
}
// NuGet: Install-Package Winnovative.WebToPdfConverter
using Winnovative;
using System;

class Program
{
    static void Main()
    {
        // Create the HTML to PDF converter
        HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

        // Set license key
        htmlToPdfConverter.LicenseKey = "your-license-key";

        // Convert HTML string to PDF
        string htmlString = "<html><body><h1>Hello World</h1></body></html>";
        byte[] pdfBytes = htmlToPdfConverter.ConvertHtml(htmlString, "");

        // Save to file
        System.IO.File.WriteAllBytes("output.pdf", pdfBytes);

        Console.WriteLine("PDF created successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF 方法:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        // Create a PDF renderer
        var renderer = new ChromePdfRenderer();

        // Convert HTML string to PDF
        string htmlString = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlString);

        // Save to file
        pdf.SaveAs("output.pdf");

        Console.WriteLine("PDF created successfully");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        // Create a PDF renderer
        var renderer = new ChromePdfRenderer();

        // Convert HTML string to PDF
        string htmlString = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlString);

        // Save to file
        pdf.SaveAs("output.pdf");

        Console.WriteLine("PDF created successfully");
    }
}
$vbLabelText   $csharpLabel

Winnovative 需要建立HtmlToPdfConverter對象,在實例上設定許可證金鑰,呼叫ConvertHtml()函數並傳入一個空的基本 URL 參數,接收原始位元組流,然後手動寫入檔案。 IronPDF 則簡化了這個過程:建立一個ChromePdfRenderer ,呼叫RenderHtmlAsPdf() ,然後使用內建的SaveAs()方法即可。

如需更進階的 HTML 轉 PDF 場景,請參閱HTML 轉 PDF 轉換指南

將 URL 轉換為 PDF

URL 轉 PDF 也呈現類似的模式。

創新制勝之道:

// NuGet: Install-Package Winnovative.WebToPdfConverter
using Winnovative;
using System;

class Program
{
    static void Main()
    {
        // Create the HTML to PDF converter
        HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

        // Set license key
        htmlToPdfConverter.LicenseKey = "your-license-key";

        // Convert URL to PDF
        string url = "https://www.example.com";
        byte[] pdfBytes = htmlToPdfConverter.ConvertUrl(url);

        // Save to file
        System.IO.File.WriteAllBytes("webpage.pdf", pdfBytes);

        Console.WriteLine("PDF from URL created successfully");
    }
}
// NuGet: Install-Package Winnovative.WebToPdfConverter
using Winnovative;
using System;

class Program
{
    static void Main()
    {
        // Create the HTML to PDF converter
        HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

        // Set license key
        htmlToPdfConverter.LicenseKey = "your-license-key";

        // Convert URL to PDF
        string url = "https://www.example.com";
        byte[] pdfBytes = htmlToPdfConverter.ConvertUrl(url);

        // Save to file
        System.IO.File.WriteAllBytes("webpage.pdf", pdfBytes);

        Console.WriteLine("PDF from URL created successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF 方法:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        // Create a PDF renderer
        var renderer = new ChromePdfRenderer();

        // Convert URL to PDF
        string url = "https://www.example.com";
        var pdf = renderer.RenderUrlAsPdf(url);

        // Save to file
        pdf.SaveAs("webpage.pdf");

        Console.WriteLine("PDF from URL created successfully");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        // Create a PDF renderer
        var renderer = new ChromePdfRenderer();

        // Convert URL to PDF
        string url = "https://www.example.com";
        var pdf = renderer.RenderUrlAsPdf(url);

        // Save to file
        pdf.SaveAs("webpage.pdf");

        Console.WriteLine("PDF from URL created successfully");
    }
}
$vbLabelText   $csharpLabel

Winnovative 使用ConvertUrl()傳回必須手動儲存的位元組。 IronPDF 為RenderUrlAsPdf()提供了一個PdfDocument對象,該物件包含SaveAs() ,方便使用。

查看指向 PDF 文件的 URL ,以了解身份驗證和自訂標頭選項。

新增頁首和頁尾

頁首和頁尾揭示了顯著的建築風格差異。 創新贏家 使用基於TextElement物件的程式化元素方法,而 IronPDF 則使用佔位符標記的基於 HTML 的標頭。

創新制勝之道:

// NuGet: Install-Package Winnovative.WebToPdfConverter
using Winnovative;
using System;
using System.Drawing;

class Program
{
    static void Main()
    {
        // Create the HTML to PDF converter
        HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

        // Set license key
        htmlToPdfConverter.LicenseKey = "your-license-key";

        // Enable header
        htmlToPdfConverter.PdfDocumentOptions.ShowHeader = true;
        htmlToPdfConverter.PdfHeaderOptions.HeaderHeight = 60;

        // Add header text
        TextElement headerText = new TextElement(0, 0, "Document Header", new Font("Arial", 12));
        htmlToPdfConverter.PdfHeaderOptions.AddElement(headerText);

        // Enable footer
        htmlToPdfConverter.PdfDocumentOptions.ShowFooter = true;
        htmlToPdfConverter.PdfFooterOptions.FooterHeight = 60;

        // Add footer with page number
        TextElement footerText = new TextElement(0, 0, "Page &p; of &P;", new Font("Arial", 10));
        htmlToPdfConverter.PdfFooterOptions.AddElement(footerText);

        // Convert HTML to PDF
        string htmlString = "<html><body><h1>Document with Header and Footer</h1><p>Content goes here</p></body></html>";
        byte[] pdfBytes = htmlToPdfConverter.ConvertHtml(htmlString, "");

        // Save to file
        System.IO.File.WriteAllBytes("document.pdf", pdfBytes);

        Console.WriteLine("PDF with header and footer created successfully");
    }
}
// NuGet: Install-Package Winnovative.WebToPdfConverter
using Winnovative;
using System;
using System.Drawing;

class Program
{
    static void Main()
    {
        // Create the HTML to PDF converter
        HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

        // Set license key
        htmlToPdfConverter.LicenseKey = "your-license-key";

        // Enable header
        htmlToPdfConverter.PdfDocumentOptions.ShowHeader = true;
        htmlToPdfConverter.PdfHeaderOptions.HeaderHeight = 60;

        // Add header text
        TextElement headerText = new TextElement(0, 0, "Document Header", new Font("Arial", 12));
        htmlToPdfConverter.PdfHeaderOptions.AddElement(headerText);

        // Enable footer
        htmlToPdfConverter.PdfDocumentOptions.ShowFooter = true;
        htmlToPdfConverter.PdfFooterOptions.FooterHeight = 60;

        // Add footer with page number
        TextElement footerText = new TextElement(0, 0, "Page &p; of &P;", new Font("Arial", 10));
        htmlToPdfConverter.PdfFooterOptions.AddElement(footerText);

        // Convert HTML to PDF
        string htmlString = "<html><body><h1>Document with Header and Footer</h1><p>Content goes here</p></body></html>";
        byte[] pdfBytes = htmlToPdfConverter.ConvertHtml(htmlString, "");

        // Save to file
        System.IO.File.WriteAllBytes("document.pdf", pdfBytes);

        Console.WriteLine("PDF with header and footer created successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF 方法:

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

class Program
{
    static void Main()
    {
        // Create a PDF renderer
        var renderer = new ChromePdfRenderer();

        // Configure header and footer
        renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
        {
            CenterText = "Document Header",
            FontSize = 12
        };

        renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
        {
            CenterText = "Page {page} of {total-pages}",
            FontSize = 10
        };

        // Convert HTML to PDF
        string htmlString = "<html><body><h1>Document with Header and Footer</h1><p>Content goes here</p></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlString);

        // Save to file
        pdf.SaveAs("document.pdf");

        Console.WriteLine("PDF with header and footer created successfully");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        // Create a PDF renderer
        var renderer = new ChromePdfRenderer();

        // Configure header and footer
        renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
        {
            CenterText = "Document Header",
            FontSize = 12
        };

        renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
        {
            CenterText = "Page {page} of {total-pages}",
            FontSize = 10
        };

        // Convert HTML to PDF
        string htmlString = "<html><body><h1>Document with Header and Footer</h1><p>Content goes here</p></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlString);

        // Save to file
        pdf.SaveAs("document.pdf");

        Console.WriteLine("PDF with header and footer created successfully");
    }
}
$vbLabelText   $csharpLabel

Winnovative 需要透過PdfDocumentOptions.ShowHeader啟用頁首/頁腳,設定高度,建立具有座標位置的TextElement物件和System.Drawing.Font對象,並使用&amp;p;&amp;P;佔位符。 IronPDF 使用TextHeaderFooter對象,其具有CenterTextFontSize等簡單屬性,以及{page}{total-pages}等直覺式佔位符。

對於具有完整 CSS 樣式的基於 HTML 的頁眉,請參閱頁眉和頁腳文檔

創新贏家 API 到 IronPDF 映射參考

此映射透過顯示直接的 API 等效項來加速遷移:

創新課堂IronPDF當量筆記
HtmlToPdfConverterChromePdfRenderer主轉換類
PdfDocumentPdfDocumentPDF 處理
PdfDocumentOptionsRenderingOptions配置
PdfHeaderOptionsHtmlHeaderFooter標題
PdfFooterOptionsHtmlHeaderFooter頁尾
TextElementHTML HtmlFragment中的 HTML文字定位
ImageElementHTML<img>圖片放置

方法映射

創新方法IronPDF 方法
ConvertUrl(url)RenderUrlAsPdf(url)
ConvertUrlToFile(url, path)RenderUrlAsPdf(url).SaveAs(path)
ConvertHtml(html, baseUrl)RenderHtmlAsPdf(html)
ConvertHtmlToFile(html, path)RenderHtmlAsPdf(html).SaveAs(path)
ConvertHtmlFile(path)RenderHtmlFileAsPdf(path)
MergePdf(streams)PdfDocument.Merge(pdfs)
AppendPdf(pdf)pdf1.AppendPdf(pdf2)

選項映射

創新之選IronPDF選項
PdfPageSize.A4PaperSize = PdfPaperSize.A4
PdfPageSize.LetterPaperSize = PdfPaperSize.Letter
PdfPageOrientation.PortraitPaperOrientation = PdfPaperOrientation.Portrait
PdfPageOrientation.LandscapePaperOrientation = PdfPaperOrientation.Landscape
TopMargin = 20MarginTop = 20
BottomMargin = 20MarginBottom = 20
LeftMargin = 15MarginLeft = 15
RightMargin = 15MarginRight = 15
ShowHeader = true設定HtmlHeader屬性
ShowFooter = true設定HtmlFooter屬性
JavaScriptEnabled = trueEnableJavaScript = true
頁碼&amp;p;頁碼{page}
總頁數&amp;P;總頁數{total-pages}

常見遷移問題及解決方案

問題一:CSS佈局看起來不一樣

症狀:在 創新贏家 中看起來"還可以"的佈局,在 IronPDF 中看起來卻不一樣了。

原因: 創新贏家 的 2016 版 WebKit 有渲染錯誤,開發人員設法繞過了這些錯誤。 IronPDF能夠以現代標準正確渲染。

解決方案:移除 創新贏家 特有的 CSS hack,使用標準 CSS:

// Clean up legacy CSS
string cleanedHtml = html
    .Replace("-webkit-flex", "flex")
    .Replace("display: -webkit-box", "display: flex");
// Clean up legacy CSS
string cleanedHtml = html
    .Replace("-webkit-flex", "flex")
    .Replace("display: -webkit-box", "display: flex");
$vbLabelText   $csharpLabel

問題 2:JavaScript 未執行

症狀: PDF 中未顯示動態內容。

原因:需要明確配置 JavaScript 等待選項。

解決方案:

renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.JavaScript(5000);
// Or wait for specific element
renderer.RenderingOptions.WaitFor.HtmlElementById("content-ready", 10000);
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.JavaScript(5000);
// Or wait for specific element
renderer.RenderingOptions.WaitFor.HtmlElementById("content-ready", 10000);
$vbLabelText   $csharpLabel

問題 3:基本 URL 無法正常運作

症狀:圖片和 CSS 的相對 URL 無法解析。

原因: IronPDF 需要明確配置基本 URL。

解決方案:

renderer.RenderingOptions.BaseUrl = new Uri("https://example.com/");
renderer.RenderingOptions.BaseUrl = new Uri("https://example.com/");
$vbLabelText   $csharpLabel

第四期:不同的分頁符

症狀:內容斷點與 創新贏家 不同。

原因:不同的渲染引擎處理分頁符號的方式不同。

解決方案:使用明確的 CSS 分頁符號控制項:

/* Control page breaks explicitly */
.no-break {
    page-break-inside: avoid;
}
.page-break-before {
    page-break-before: always;
}
.page-break-after {
    page-break-after: always;
}

問題五:字體看起來不一樣

症狀:文字顯示的字體與預期不符。

原因: IronPDF 使用了系統字型; 網頁字體需要明確載入。

解決方案:

<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

body {
    font-family: 'Roboto', Arial, sans-serif;
}
</style>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

body {
    font-family: 'Roboto', Arial, sans-serif;
}
</style>
HTML

創新贏家 遷移清單

遷移前任務

審核您的程式碼庫,找出所有 創新贏家 的使用情況:

# Find all 創新贏家 references
grep -r "Winnovative" --include="*.cs" .
grep -r "HtmlToPdfConverter" --include="*.cs" .
grep -r "PdfDocumentOptions" --include="*.cs" .
grep -r "ConvertUrl\|ConvertHtml" --include="*.cs" .
# Find all 創新贏家 references
grep -r "Winnovative" --include="*.cs" .
grep -r "HtmlToPdfConverter" --include="*.cs" .
grep -r "PdfDocumentOptions" --include="*.cs" .
grep -r "ConvertUrl\|ConvertHtml" --include="*.cs" .
SHELL

記錄目前配置,包括頁面大小、邊距和頁首/頁尾設定。 找出可以移除的 CSS 變通方案(webkit 前綴、基於浮動的網格)。 請注意 JavaScript 相容性要求。

程式碼更新任務

  1. 刪除 創新贏家 NuGet 套件
  2. 安裝 IronPdf NuGet 套件
  3. 將所有命名空間導入從Winnovative更新為IronPdf
  4. HtmlToPdfConverter替換為ChromePdfRenderer
  5. ConvertHtml()調用轉換為RenderHtmlAsPdf()調用
  6. ConvertUrl()呼叫轉換為RenderUrlAsPdf()調用
  7. 將頁面大小/方向設定更新至RenderingOptions
  8. 轉換邊距配置
  9. 將基於TextElement頁首/頁尾遷移到基於 HTML 的TextHeaderFooter
  10. 將頁碼佔位符從&amp;p; / &amp;P;更新為{page} / {total-pages}
  11. 啟動時加入 IronPDF 許可證初始化

遷移後測試

遷移完成後,請確認以下幾個面向:

  • 測試基本的 HTML 到 PDF 轉換
  • 測試 URL 到 PDF 的轉換
  • 驗證 CSS Grid 佈局是否正確渲染(現在可以正常工作了)
  • 驗證 Flexbox 佈局是否正確渲染(現在應該可以正常運作了)
  • 使用現代 ES6+ 語法測試大量使用 JavaScript 的頁面
  • 驗證 Bootstrap 5 相容性
  • 測試頁首/頁尾渲染
  • 檢查分頁符
  • 比較 PDF 輸出質量

清理任務

  • 移除 創新贏家 CSS 變通方案(webkit 前綴)
  • 將 ES5 JavaScript 更新為現代語法
  • 移除基於浮點數的網格回退方案
  • 更新文檔

遷移到 IronPDF 的主要優勢

從 創新贏家 遷移到 IronPDF 可帶來以下幾個關鍵優勢:

現代渲染引擎: IronPDF 使用最新的 Chromium 引擎,確保完全支援 CSS3、CSS Grid、Flexbox 和 ES2024 JavaScript。 Bootstrap 5、Tailwind CSS 和 React/Vue 等現代框架都能正確渲染。

簡化 API:基於 HTML 的頁首和頁尾取代了程式化的TextElement定位。 直觀的佔位符(例如{page}取代了晦澀的&amp;p;語法。 內建的SaveAs()方法無需手動處理位元組。

積極開發:隨著 .NET 10 和 C# 14 的普及,IronPDF 的每月更新確保了與當前和未來 .NET 版本的兼容性。

現代 CSS 無需變通方法: CSS Grid、Flexbox 和現代排版無需 webkit 前綴或基於浮動的回退方案即可運作。

現代 JavaScript: ES6+ 特性,包括箭頭函數、async/await、類別和模組,都能正確執行。

柯蒂斯·週
技術撰稿人

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

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