如何用 C# 從 CraftMyPDF 轉移到 IronPDF
為什麼要從CraftMyPDF轉移到 IronPDF?
CraftMyPDF 等基於雲端的 PDF API 引進了一些基本問題,使其不適合許多生產環境。
基於雲的 PDF API 的問題
1.您的資料離開您的系統:每個 HTML 範本和 JSON 資料有效負載都會傳送到CraftMyPDF的伺服器。 對於發票、合約、醫療記錄或任何敏感的商業資料,這會造成 HIPAA、GDPR 和 SOC2 的合規風險。
2.網路延遲:CraftMyPDF自己的文件指出,每個 PDF 需要 1.5-30 秒。IronPDF以毫秒為單位在本地產生。
3.每個 PDF 的成本累積起來:每月 10,000 個 PDF 按訂閱費率計算會產生大量的經常性成本,而一次性永久許可則不然。
4.針對列印最佳化的輸出:雲端 API 通常會針對列印進行最佳化-減少背景並簡化顏色以節省"墨水"。因此,最終輸出結果與螢幕上顯示的 HTML 程式碼看起來截然不同。
5.模板鎖定:CraftMyPDF需要使用其專有的拖放編輯器。 不能隨意使用標準的 HTML/CSS。
架構比較
| 範疇 | CraftMyPDF | IronPDF |
|---|---|---|
| 資料位置 | 雲端 (您的資料離開您的系統) | 內部部署(資料不離手) |
| 交稿時間 | 1.每個 PDF 需時 5-30 秒 | 毫秒 |
| 定價 | 按 PDF 訂閱 | 一次性永久授權 |
| 範本系統 | 僅限專屬拖放 | 任何 HTML/CSS/JavaScript |
| 輸出品質 | 印刷最佳化 | 完美的畫面呈現 |
| 離線工作 | 無(需要網際網路) | 是 |
| 合規性 | 資料葉組織 | SOC2/HIPAA 友好 |
功能對比
| 特點 | CraftMyPDF | IronPDF |
|---|---|---|
| HTML 至 PDF | 透過 API 範本 | ✅ 原生 |
| URL 至 PDF | 透過 API | ✅ 原生 |
| 自訂範本 | 僅限專屬編輯器 | ✅ 任何 HTML |
| 支援 CSS3 | 限額 | ✅ 全文 |
| JavaScript 渲染 | 限額 | ✅ 全文 |
| 合併/分割 PDF | 透過 API | ✅ 原生 |
| 水印 | 透過 API | ✅ 原生 |
| 離線工作 | ❌ | ✅ |
| 自行託管 | ❌ | ✅ |
遷移前的準備工作
先決條件
確保您的環境符合這些要求:
- .NET Framework 4.6.2+ 或 .NET Core 3.1 / .NET 5-9
- Visual Studio 2019+ 或具有 C# 擴充功能的 VS Code
- NuGet 套件管理員存取權限 -IronPDF授權金鑰 (可於 ironpdf.com 網站免費試用)
審核CraftMyPDF使用情況
在您的解決方案目錄中執行這些指令,以識別所有CraftMyPDF引用:
# Find allCraftMyPDFusages in your codebase
grep -r "CraftMyPdf\|craftmypdf\|api.craftmypdf.com" --include="*.cs" .
grep -r "X-API-KEY" --include="*.cs" .
# Find API key references
grep -r "your-api-key\|template-id\|template_id" --include="*.cs" .
# Find NuGet package references
grep -r "CraftMyPdf\|RestSharp" --include="*.csproj" .
# Find allCraftMyPDFusages in your codebase
grep -r "CraftMyPdf\|craftmypdf\|api.craftmypdf.com" --include="*.cs" .
grep -r "X-API-KEY" --include="*.cs" .
# Find API key references
grep -r "your-api-key\|template-id\|template_id" --include="*.cs" .
# Find NuGet package references
grep -r "CraftMyPdf\|RestSharp" --include="*.csproj" .
可預期的重大變更
| 變更 | CraftMyPDF | IronPDF | 影響力 |
|---|---|---|---|
| 架構 | 雲端 REST API | 本地 .NET 圖書館 | 移除 HTTP 呼叫 |
| 範本 | 專屬編輯器 | 標準 HTML | 將範本轉換為 HTML |
| API關鍵字 | 每次通話都需要 | 啟動時的授權 | 移除 API 金鑰處理 |
| 同步模式 | 必須 (HTTP) | 選項 | 如果喜歡,請移除等待 |
| 錯誤處理 | HTTP 狀態代碼 | 例外情況 | 變更 try/catch 模式 |
| 資料綁定 | JSON 範本 | 字串插值 | 簡化資料綁定 |
逐步遷移的過程
步驟 1:更新 NuGet 套件
移除 HTTP 客戶端函式庫,並安裝 IronPDF:
# Remove RestSharp HTTP client
dotnet remove package RestSharp
# Install IronPDF
dotnet add package IronPdf
# Remove RestSharp HTTP client
dotnet remove package RestSharp
# Install IronPDF
dotnet add package IronPdf
步驟 2:更新命名空間參考資料
用IronPDF取代 HTTP 客戶端命名空間:
// Remove these
using RestSharp;
using System.IO;
// Add this
using IronPdf;
// Remove these
using RestSharp;
using System.IO;
// Add this
using IronPdf;
Imports IronPdf
步驟 3:配置授權(啟動時一次)
使用單一授權組態取代每次要求的 API 金鑰標頭:
// Add at application startup (Program.cs or Global.asax)
// This replaces all X-API-KEY headers
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Global.asax)
// This replaces all X-API-KEY headers
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Global.asax)
' This replaces all X-API-KEY headers
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
完整的 API 遷移參考。
API 端點映射
| CraftMyPDF | IronPDF |
|---|---|
POST /v1/create |
renderer.RenderHtmlAsPdf(html) |
X-API-KEY 標頭 |
License.LicenseKey = "..." |
template_id |
標準 HTML 字串 |
{%name%}佔位符 |
$"{name}" C# 內插 |
POST /v1/merge |
PdfDocument.Merge(pdfs) |
POST /v1/add-watermark |
pdf.ApplyWatermark(html) |
| Webhook 回呼 | 不需要 |
| 費率限制 | 不適用 |
配置映射
| CraftMyPDF 選項 | IronPDF 同等級產品 |
|---|---|
template_id |
HTML 字串 |
data JSON |
C# 插值 |
page_size: "A4" |
PaperSize = PdfPaperSize.A4 |
orientation: "landscape" |
PaperOrientation = Landscape |
margin_top: 20 |
MarginTop = 20 |
header |
HtmlHeader |
footer |
HtmlFooter |
程式碼遷移範例
HTML 至 PDF 轉換
最常見的操作展示了從雲 API 到本機渲染的基本架構轉換。
CraftMyPDF 實作:
// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;
class Program
{
static void Main()
{
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
request.AddJsonBody(new
{
template_id = "your-template-id",
data = new
{
html = "<h1>Hello World</h1><p>This is a PDF from HTML</p>"
}
});
var response = client.Execute(request);
File.WriteAllBytes("output.pdf", response.RawBytes);
}
}
// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;
class Program
{
static void Main()
{
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
request.AddJsonBody(new
{
template_id = "your-template-id",
data = new
{
html = "<h1>Hello World</h1><p>This is a PDF from HTML</p>"
}
});
var response = client.Execute(request);
File.WriteAllBytes("output.pdf", response.RawBytes);
}
}
Imports System
Imports RestSharp
Imports System.IO
Module Program
Sub Main()
Dim client As New RestClient("https://api.craftmypdf.com/v1/create")
Dim request As New RestRequest(Method.POST)
request.AddHeader("X-API-KEY", "your-api-key")
request.AddJsonBody(New With {
.template_id = "your-template-id",
.data = New With {
.html = "<h1>Hello World</h1><p>This is a PDF from HTML</p>"
}
})
Dim response = client.Execute(request)
File.WriteAllBytes("output.pdf", response.RawBytes)
End Sub
End Module
IronPDF 實作:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML</p>");
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML</p>");
pdf.SaveAs("output.pdf");
}
}
Imports System
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML</p>")
pdf.SaveAs("output.pdf")
End Sub
End Class
IronPDF 省去了 RestClient 設定、API key headers、模板 ID 和 HTTP 回應處理 - 將 15 行的雲端作業減至 4 行本機程式碼。 如需更多選項,請參閱 HTML to PDF 文件。
URL 轉 PDF
CraftMyPDF 實作:
// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;
class Program
{
static void Main()
{
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
request.AddJsonBody(new
{
template_id = "your-template-id",
data = new
{
url = "https://example.com"
},
export_type = "pdf"
});
var response = client.Execute(request);
File.WriteAllBytes("webpage.pdf", response.RawBytes);
}
}
// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;
class Program
{
static void Main()
{
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
request.AddJsonBody(new
{
template_id = "your-template-id",
data = new
{
url = "https://example.com"
},
export_type = "pdf"
});
var response = client.Execute(request);
File.WriteAllBytes("webpage.pdf", response.RawBytes);
}
}
Imports System
Imports RestSharp
Imports System.IO
Module Program
Sub Main()
Dim client As New RestClient("https://api.craftmypdf.com/v1/create")
Dim request As New RestRequest(Method.POST)
request.AddHeader("X-API-KEY", "your-api-key")
request.AddJsonBody(New With {
.template_id = "your-template-id",
.data = New With {
.url = "https://example.com"
},
.export_type = "pdf"
})
Dim response = client.Execute(request)
File.WriteAllBytes("webpage.pdf", response.RawBytes)
End Sub
End Module
IronPDF 實作:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}
Imports System
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Class
IronPDF 的 RenderUrlAsPdf 方法可以擷取完整的網頁,包括 JavaScript 渲染的內容。 如需更多選項,請參閱 URL 至 PDF 文件。
頁首和頁尾
CraftMyPDF 實作:
// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;
class Program
{
static void Main()
{
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
request.AddJsonBody(new
{
template_id = "your-template-id",
data = new
{
html = "<h1>Document Content</h1>",
header = "<div>Page Header</div>",
footer = "<div>Page {page} of {total_pages}</div>"
}
});
var response = client.Execute(request);
File.WriteAllBytes("document.pdf", response.RawBytes);
}
}
// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;
class Program
{
static void Main()
{
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
request.AddJsonBody(new
{
template_id = "your-template-id",
data = new
{
html = "<h1>Document Content</h1>",
header = "<div>Page Header</div>",
footer = "<div>Page {page} of {total_pages}</div>"
}
});
var response = client.Execute(request);
File.WriteAllBytes("document.pdf", response.RawBytes);
}
}
Imports System
Imports RestSharp
Imports System.IO
Module Program
Sub Main()
Dim client As New RestClient("https://api.craftmypdf.com/v1/create")
Dim request As New RestRequest(Method.POST)
request.AddHeader("X-API-KEY", "your-api-key")
request.AddJsonBody(New With {
.template_id = "your-template-id",
.data = New With {
.html = "<h1>Document Content</h1>",
.header = "<div>Page Header</div>",
.footer = "<div>Page {page} of {total_pages}</div>"
}
})
Dim response = client.Execute(request)
File.WriteAllBytes("document.pdf", response.RawBytes)
End Sub
End Module
IronPDF 實作:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
CenterText = "Page Header"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
{
CenterText = "Page {page} of {total-pages}"
};
var pdf = renderer.RenderHtmlAsPdf("<h1>Document Content</h1>");
pdf.SaveAs("document.pdf");
}
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
CenterText = "Page Header"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
{
CenterText = "Page {page} of {total-pages}"
};
var pdf = renderer.RenderHtmlAsPdf("<h1>Document Content</h1>");
pdf.SaveAs("document.pdf");
}
}
Imports System
Imports IronPdf
Imports IronPdf.Rendering
Module Program
Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter() With {
.CenterText = "Page Header"
}
renderer.RenderingOptions.TextFooter = New TextHeaderFooter() With {
.CenterText = "Page {page} of {total-pages}"
}
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Document Content</h1>")
pdf.SaveAs("document.pdf")
End Sub
End Module
IronPDF 支援像 {page} 和 {total-pages} 這樣的佔位標記,用於動態頁碼。 如需更多選項,請參閱 headers and footers 文件。
範本變數轉換
CraftMyPDF 使用專屬的範本占位符,必須轉換為 C# 字串插值:
CraftMyPDF模式:
//CraftMyPDFtemplate variables
request.AddJsonBody(new
{
template_id = "invoice-template",
data = new
{
customer = "John Doe",
amount = "$1,000",
items = invoiceItems
}
});
//CraftMyPDFtemplate variables
request.AddJsonBody(new
{
template_id = "invoice-template",
data = new
{
customer = "John Doe",
amount = "$1,000",
items = invoiceItems
}
});
'CraftMyPDFtemplate variables
request.AddJsonBody(New With {
.template_id = "invoice-template",
.data = New With {
.customer = "John Doe",
.amount = "$1,000",
.items = invoiceItems
}
})
IronPDF模式:
// C# string interpolation
var html = $@"
<html>
<body>
<h1>Invoice</h1>
<p>Customer: {customerName}</p>
<p>Amount: {amount}</p>
{GenerateItemsTable(invoiceItems)}
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
// C# string interpolation
var html = $@"
<html>
<body>
<h1>Invoice</h1>
<p>Customer: {customerName}</p>
<p>Amount: {amount}</p>
{GenerateItemsTable(invoiceItems)}
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
Dim html As String = $"
<html>
<body>
<h1>Invoice</h1>
<p>Customer: {customerName}</p>
<p>Amount: {amount}</p>
{GenerateItemsTable(invoiceItems)}
</body>
</html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
關鍵遷移注意事項
移除所有 HTTP 程式碼
最重要的改變是消除網路的依賴性。IronPDF在本機執行 - 無須 RestClient、無須呼叫 API、無須處理回應:
//CraftMyPDF- HTTP required
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
var response = await client.ExecuteAsync(request);
//IronPDF- no HTTP
var pdf = renderer.RenderHtmlAsPdf(html);
//CraftMyPDF- HTTP required
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
var response = await client.ExecuteAsync(request);
//IronPDF- no HTTP
var pdf = renderer.RenderHtmlAsPdf(html);
Imports RestSharp
'CraftMyPDF- HTTP required
Dim client As New RestClient("https://api.craftmypdf.com/v1/create")
Dim request As New RestRequest(Method.POST)
request.AddHeader("X-API-KEY", "your-api-key")
Dim response = Await client.ExecuteAsync(request)
'IronPDF- no HTTP
Dim pdf = renderer.RenderHtmlAsPdf(html)
移除速率限制程式碼
CraftMyPDF 施加 API 速率限制,需要重試邏輯。IronPDF沒有限制:
//CraftMyPDF- needed to avoid 429 errors
await Task.Delay(100);
if (response.StatusCode == TooManyRequests) { /* retry */ }
//IronPDF- no limits, just generate
var pdf = renderer.RenderHtmlAsPdf(html);
// Remove all rate limit code!
//CraftMyPDF- needed to avoid 429 errors
await Task.Delay(100);
if (response.StatusCode == TooManyRequests) { /* retry */ }
//IronPDF- no limits, just generate
var pdf = renderer.RenderHtmlAsPdf(html);
// Remove all rate limit code!
移除 Webhook 處理器
CraftMyPDF 使用 async webhooks 來完成 PDF。IronPDF是同步的,PDF 可以立即完成:
//CraftMyPDF- webhook callback required
// POST with webhook_url, wait for callback
//IronPDF- PDF ready immediately
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// No callback needed!
//CraftMyPDF- webhook callback required
// POST with webhook_url, wait for callback
//IronPDF- PDF ready immediately
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// No callback needed!
'CraftMyPDF- webhook callback required
' POST with webhook_url, wait for callback
'IronPDF- PDF ready immediately
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
' No callback needed!
預設同步
如果僅需用於 HTTP 呼叫,則移除 async/await 模式:
//CraftMyPDF- async required
var response = await client.ExecuteAsync(request);
//IronPDF- sync by default (async available if needed)
var pdf = renderer.RenderHtmlAsPdf(html);
//CraftMyPDF- async required
var response = await client.ExecuteAsync(request);
//IronPDF- sync by default (async available if needed)
var pdf = renderer.RenderHtmlAsPdf(html);
遷移後檢查清單
完成程式碼遷移後,請驗證下列事項:
- 執行所有 PDF 生成測試
- 比較輸出品質(IronPDF 的 Chromium 引擎可實現像素級完美渲染)
- 衡量效能提升(毫秒與秒)
- 驗證所有範本是否已正確轉換
- 測試無速率限制的批量處理
- 在所有目標環境中進行測試
- 更新 CI/CD 管線 取消CraftMyPDF訂閱
- 從 secrets/config 移除 API 金鑰
讓您的 PDF 基礎架構面向未來
由於 .NET 10 即將推出,而 C# 14 也將引進新的語言功能,因此選擇本機 PDF 函式庫可消除雲端 API 廢棄的風險和版本相容性的疑慮。IronPDF的永久授權模式意味著您的遷移投資可以無限期地獲得回報,因為專案可以延續到 2025 年和 2026 年 - 而無需經常性的訂閱成本或資料離開您的基礎架構。
其他資源
從CraftMyPDF遷移到IronPDF可消除雲端依賴、網路延遲、每張 PDF 成本和模板鎖定,同時提供離線執行的像素完美 Chromium 演算。從 REST API 呼叫轉換到本機方法調用,可簡化您的程式碼庫,並將敏感的文件資料保留在您的基礎架構中。

