如何在 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>IronPDF 與 Winnovative:功能對比
了解架構差異有助於技術決策者評估遷移投資:
| 方面 | 創新贏家 | IronPDF |
|---|---|---|
| 渲染引擎 | WebKit(2016) | 鉻(電流) |
| CSS Grid | 不支援。 | 全力支持 |
| Flexbox | 布吉 | 全力支持 |
| JavaScript | 僅限 ES5 | ES2024 |
| 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安裝 IronPDF:
# Install IronPDF
dotnet add package IronPdf# Install IronPDF
dotnet add package IronPdf步驟 2:更新命名空間
將 創新贏家 命名空間替換為 IronPdf 命名空間:
// Before (Winnovative)
using Winnovative;
using Winnovative.WebKit;
// After (IronPDF)
using IronPdf;// Before (Winnovative)
using Winnovative;
using Winnovative.WebKit;
// After (IronPDF)
using IronPdf;步驟 3:初始化許可證
在應用程式啟動時新增許可證初始化:
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";程式碼遷移範例
將 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");
}
}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");
}
}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");
}
}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");
}
}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");
}
}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");
}
}Winnovative 需要透過PdfDocumentOptions.ShowHeader啟用頁首/頁腳,設定高度,建立具有座標位置的TextElement物件和System.Drawing.Font對象,並使用&p;和&P;佔位符。 IronPDF 使用TextHeaderFooter對象,其具有CenterText和FontSize等簡單屬性,以及{page}和{total-pages}等直覺式佔位符。
對於具有完整 CSS 樣式的基於 HTML 的頁眉,請參閱頁眉和頁腳文檔。
創新贏家 API 到 IronPDF 映射參考
此映射透過顯示直接的 API 等效項來加速遷移:
| 創新課堂 | IronPDF當量 | 筆記 |
|---|---|---|
HtmlToPdfConverter | ChromePdfRenderer | 主轉換類 |
PdfDocument | PdfDocument | PDF 處理 |
PdfDocumentOptions | RenderingOptions | 配置 |
PdfHeaderOptions | HtmlHeaderFooter | 標題 |
PdfFooterOptions | HtmlHeaderFooter | 頁尾 |
TextElement | HTML HtmlFragment中的 HTML | 文字定位 |
ImageElement | HTML<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.A4 | PaperSize = PdfPaperSize.A4 |
PdfPageSize.Letter | PaperSize = PdfPaperSize.Letter |
PdfPageOrientation.Portrait | PaperOrientation = PdfPaperOrientation.Portrait |
PdfPageOrientation.Landscape | PaperOrientation = PdfPaperOrientation.Landscape |
TopMargin = 20 | MarginTop = 20 |
BottomMargin = 20 | MarginBottom = 20 |
LeftMargin = 15 | MarginLeft = 15 |
RightMargin = 15 | MarginRight = 15 |
ShowHeader = true | 設定HtmlHeader屬性 |
ShowFooter = true | 設定HtmlFooter屬性 |
JavaScriptEnabled = true | EnableJavaScript = true |
頁碼&p; | 頁碼{page} |
總頁數&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");問題 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);問題 3:基本 URL 無法正常運作
症狀:圖片和 CSS 的相對 URL 無法解析。
原因: IronPDF 需要明確配置基本 URL。
解決方案:
renderer.RenderingOptions.BaseUrl = new Uri("https://example.com/");renderer.RenderingOptions.BaseUrl = new Uri("https://example.com/");第四期:不同的分頁符
症狀:內容斷點與 創新贏家 不同。
原因:不同的渲染引擎處理分頁符號的方式不同。
解決方案:使用明確的 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>創新贏家 遷移清單
遷移前任務
審核您的程式碼庫,找出所有 創新贏家 的使用情況:
# 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" .記錄目前配置,包括頁面大小、邊距和頁首/頁尾設定。 找出可以移除的 CSS 變通方案(webkit 前綴、基於浮動的網格)。 請注意 JavaScript 相容性要求。
程式碼更新任務
- 刪除 創新贏家 NuGet 套件
- 安裝 IronPdf NuGet 套件
- 將所有命名空間導入從
Winnovative更新為IronPdf - 將
HtmlToPdfConverter替換為ChromePdfRenderer - 將
ConvertHtml()調用轉換為RenderHtmlAsPdf()調用 - 將
ConvertUrl()呼叫轉換為RenderUrlAsPdf()調用 - 將頁面大小/方向設定更新至
RenderingOptions中 - 轉換邊距配置
- 將基於
TextElement頁首/頁尾遷移到基於 HTML 的TextHeaderFooter - 將頁碼佔位符從
&p;/&P;更新為{page}/{total-pages} - 啟動時加入 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}取代了晦澀的&p;語法。 內建的SaveAs()方法無需手動處理位元組。
積極開發:隨著 .NET 10 和 C# 14 的普及,IronPDF 的每月更新確保了與當前和未來 .NET 版本的兼容性。
現代 CSS 無需變通方法: CSS Grid、Flexbox 和現代排版無需 webkit 前綴或基於浮動的回退方案即可運作。
現代 JavaScript: ES6+ 特性,包括箭頭函數、async/await、類別和模組,都能正確執行。






