如何使用 C# 將 SAP Crystal Reports 移轉到 IronPDF
從 SAP Crystal Reports 遷移到 IronPDF 會將您的報表工作流程從具有複雜部署需求的笨重傳統平台轉變為現代、輕量級的 NuGet 套件。 本指南提供了一條完整的、分步的遷移路徑,消除了 500MB 以上的龐大運行時安裝,解除了 SAP 生態系統鎖定,並實現了對 .NET Core/5/6/7/8+ 的全面支援。
為什麼要從 SAP Crystal Reports 遷移到 IronPDF
了解 SAP Crystal Reports
SAP Crystal Reports 在企業領域中脫穎而出,成為一款能夠產生動態且"像素級完美"報表的工具。 SAP Crystal Reports 因其能夠連接多種資料來源而備受認可,一直是許多尋求全面報表功能的企業的首選解決方案。 該平台憑藉其 Crystal Reports Designer 提供了無與倫比的強大功能,可簡化複雜報表佈局的建置。
然而,隨著技術的進步,SAP Crystal Reports 對 SAP 框架的嚴重依賴以及其苛刻的安裝和部署要求不容忽視。 由於其龐大的體積,企業通常需要投入大量資源和時間來全面實施和維護該系統。
遷移的主要原因
1.安裝過程龐大: Crystal Reports 運行時庫大小超過 500MB,安裝過程較為複雜。
- SAP生態系鎖定:與SAP的定價、支援週期及產品路線圖緊密相關 3.複雜的授權模式:採用 SAP 企業銷售流程的按處理器/按使用者授權模式 4.傳統架構: 32 位元 COM 相依性使現代 64 位元部署變得複雜 5.已棄用對 .NET Core 的支援:對現代 .NET 平台的支援有限 6.報表設計器相依性:需要 Visual Studio 擴充或獨立設計器 7.效能緩慢:運行時初始化耗時過長,記憶體佔用過高。
SAP Crystal Reports的隱性成本
| 成本因素 | SAP Crystal Reports | IronPDF |
|---|---|---|
| 運行時大小 | 500MB以上 | 約20MB |
| 安裝 | 複雜的 MSI/安裝程序 | NuGet 套件 |
| 部署 | 專業安裝人員 | xcopy |
| 64 位元支持 | 有問題的 | 本國的 |
| .NET Core/5/6/7/8 | 有限的 | 全力支持 |
| 雲端部署 | 難的 | 簡單的 |
| Linux/Docker | 不 | 是的 |
SAP Crystal Reports 與 IronPDF 對比
| 特徵 | SAP Crystal Reports | IronPDF |
|---|---|---|
| 主要功能 | 企業報告平台 | HTML 轉 PDF 轉換引擎與 PDF 處理 |
| 一體化 | 在 SAP 生態系中表現最佳 | 現代 .NET 集成,輕量級 NuGet 包 |
| 易用性 | 複雜的設定和部署 | 簡化集成,支援 .NET 開發人員 |
| 報表設計器 | 必需的 | 可選(HTML/CSS) |
| 範本格式 | .rpt(二進位) | HTML/CSS |
| HTML 轉 PDF | 不 | 全鉻 |
| PDF檔案的URL | 不 | 是的 |
| CSS 支援 | 不 | 完整的 CSS3 |
| JavaScript | 不 | 完整版 ES2024 |
| PDF 處理 | 不 | 完整(合併、拆分、編輯) |
| 數位簽名 | 不 | 是的 |
| PDF/A 合規性 | 不 | 是的 |
| 現代意義 | 衰落,被現代替代品取代 | 現代化的,與當代科技完美融合 |
對於計劃在 2025 年和 2026 年採用 .NET 10 和 C# 14 的團隊,IronPDF 提供了 SAP Crystal Reports 無法提供的原生跨平台支援。
開始之前
先決條件
- .NET 環境: .NET框架 4.6.2+ 或 .NET Core 3.1+ / .NET 5/6/7/8/9+
- NuGet 存取權限:能夠安裝 NuGet 套件
- IronPDF 許可證:請從ironpdf.com取得您的許可證密鑰。
NuGet 套件變更
# Remove Crystal Reports packages
dotnet remove package CrystalDecisions.CrystalReports.Engine
dotnet remove package CrystalDecisions.Shared
dotnet remove package CrystalDecisions.ReportAppServer
dotnet remove package CrystalDecisions.Web
# Remove legacy assemblies from project references
# Install IronPDF
dotnet add package IronPdf# Remove Crystal Reports packages
dotnet remove package CrystalDecisions.CrystalReports.Engine
dotnet remove package CrystalDecisions.Shared
dotnet remove package CrystalDecisions.ReportAppServer
dotnet remove package CrystalDecisions.Web
# Remove legacy assemblies from project references
# Install IronPDF
dotnet add package IronPdf許可證配置
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";完整 API 參考
命名空間變更
// Before: SAP Crystal Reports
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using CrystalDecisions.ReportAppServer;
// After: IronPDF
using IronPdf;// Before: SAP Crystal Reports
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using CrystalDecisions.ReportAppServer;
// After: IronPDF
using IronPdf;核心 API 映射
| SAP Crystal Reports | IronPDF | 筆記 |
|---|---|---|
ReportDocument | ChromePdfRenderer | 核心渲染 |
ReportDocument.Load() | RenderHtmlAsPdf() | 載入內容 |
.rpt文件 | HTML/CSS模板 | 範本格式 |
SetDataSource() | 包含資料的 HTML | 資料綁定 |
SetParameterValue() | 字串插值 | 參數 |
ExportToDisk() | pdf.SaveAs() | 儲存檔案 |
ExportToStream() | pdf.BinaryData | 取得位元組 |
PrintToPrinter() | pdf.Print() | 印刷 |
Database.Tables | C# 資料存取 | 數據來源 |
FormulaFieldDefinitions | C# 邏輯 | 計算 |
SummaryInfo | pdf.MetaData | PDF元數據 |
ExportFormatType.PortableDocFormat | 預設輸出 | PDF原生 |
程式碼遷移範例
範例 1:HTML 轉 PDF
之前(SAP Crystal Reports):
// NuGet: Install-Package CrystalReports.Engine
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System;
class Program
{
static void Main()
{
// Crystal Reports requires a .rpt file template
ReportDocument reportDocument = new ReportDocument();
reportDocument.Load("Report.rpt");
// Crystal Reports doesn't directly support HTML
// You need to bind data to the report template
// reportDocument.SetDataSource(dataSet);
ExportOptions exportOptions = reportDocument.ExportOptions;
exportOptions.ExportDestinationType = ExportDestinationType.DiskFile;
exportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
DiskFileDestinationOptions diskOptions = new DiskFileDestinationOptions();
diskOptions.DiskFileName = "output.pdf";
exportOptions.DestinationOptions = diskOptions;
reportDocument.Export();
reportDocument.Close();
reportDocument.Dispose();
}
}// NuGet: Install-Package CrystalReports.Engine
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System;
class Program
{
static void Main()
{
// Crystal Reports requires a .rpt file template
ReportDocument reportDocument = new ReportDocument();
reportDocument.Load("Report.rpt");
// Crystal Reports doesn't directly support HTML
// You need to bind data to the report template
// reportDocument.SetDataSource(dataSet);
ExportOptions exportOptions = reportDocument.ExportOptions;
exportOptions.ExportDestinationType = ExportDestinationType.DiskFile;
exportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
DiskFileDestinationOptions diskOptions = new DiskFileDestinationOptions();
diskOptions.DiskFileName = "output.pdf";
exportOptions.DestinationOptions = diskOptions;
reportDocument.Export();
reportDocument.Close();
reportDocument.Dispose();
}
}(IronPDF 之後):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
// Create a PDF from HTML string
var renderer = new ChromePdfRenderer();
string htmlContent = "<h1>Hello World</h1><p>This is a PDF generated from HTML.</p>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
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 from HTML string
var renderer = new ChromePdfRenderer();
string htmlContent = "<h1>Hello World</h1><p>This is a PDF generated from HTML.</p>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully!");
}
}這個例子體現了根本性的範式差異。 SAP Crystal Reports 需要一個預先設計的.rpt檔案模板,該模板在 Crystal Reports Designer 中創建,然後您必須配置ExportOptions 、 ExportDestinationType 、 ExportFormatType和DiskFileDestinationOptions 。 該庫不直接支援 HTML 內容—您必須將資料綁定到報表範本。
IronPDF 直接接受 HTML 字串:建立一個ChromePdfRenderer ,使用任何 HTML 內容呼叫RenderHtmlAsPdf() ,然後SaveAs() 。 無需設計師,無需二進位模板,無需複雜的匯出配置。 請參閱HTML 轉 PDF 文件以取得完整範例。
範例 2:URL 轉 PDF
之前(SAP Crystal Reports):
// NuGet: Install-Package CrystalReports.Engine
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System;
using System.Net;
class Program
{
static void Main()
{
// Crystal Reports cannot directly convert URLs to PDF
// You need to create a report template first
// Download HTML content
WebClient client = new WebClient();
string htmlContent = client.DownloadString("https://example.com");
// Crystal Reports requires .rpt template and data binding
// This approach is not straightforward for URL conversion
ReportDocument reportDocument = new ReportDocument();
reportDocument.Load("WebReport.rpt");
// Manual data extraction and binding required
// reportDocument.SetDataSource(extractedData);
reportDocument.ExportToDisk(ExportFormatType.PortableDocFormat, "output.pdf");
reportDocument.Close();
reportDocument.Dispose();
}
}// NuGet: Install-Package CrystalReports.Engine
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System;
using System.Net;
class Program
{
static void Main()
{
// Crystal Reports cannot directly convert URLs to PDF
// You need to create a report template first
// Download HTML content
WebClient client = new WebClient();
string htmlContent = client.DownloadString("https://example.com");
// Crystal Reports requires .rpt template and data binding
// This approach is not straightforward for URL conversion
ReportDocument reportDocument = new ReportDocument();
reportDocument.Load("WebReport.rpt");
// Manual data extraction and binding required
// reportDocument.SetDataSource(extractedData);
reportDocument.ExportToDisk(ExportFormatType.PortableDocFormat, "output.pdf");
reportDocument.Close();
reportDocument.Dispose();
}
}(IronPDF 之後):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
// Create a PDF from a URL
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created from URL successfully!");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
// Create a PDF from a URL
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created from URL successfully!");
}
}SAP Crystal Reports 無法直接將 URL 轉換為 PDF。 您需要使用WebClient手動下載 HTML 內容,然後以某種方式提取該資料並將其綁定到預先設計的.rpt模板—這個過程並不直接,需要大量的手動工作。
IronPDF 的RenderUrlAsPdf()方法只需一次呼叫即可擷取包含所有 CSS、JavaScript 和影像的完整渲染網頁。 了解更多信息,請閱讀我們的教程。
範例 3:帶頁碼的頁首和頁尾
之前(SAP Crystal Reports):
// NuGet: Install-Package CrystalReports.Engine
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System;
class Program
{
static void Main()
{
// Crystal Reports requires design-time configuration
ReportDocument reportDocument = new ReportDocument();
reportDocument.Load("Report.rpt");
// Headers and footers must be designed in the .rpt file
// using Crystal Reports designer
// You can set parameter values programmatically
reportDocument.SetParameterValue("HeaderText", "Company Name");
reportDocument.SetParameterValue("FooterText", "Page ");
// Crystal Reports handles page numbers through formula fields
// configured in the designer
reportDocument.ExportToDisk(ExportFormatType.PortableDocFormat, "output.pdf");
reportDocument.Close();
reportDocument.Dispose();
}
}// NuGet: Install-Package CrystalReports.Engine
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System;
class Program
{
static void Main()
{
// Crystal Reports requires design-time configuration
ReportDocument reportDocument = new ReportDocument();
reportDocument.Load("Report.rpt");
// Headers and footers must be designed in the .rpt file
// using Crystal Reports designer
// You can set parameter values programmatically
reportDocument.SetParameterValue("HeaderText", "Company Name");
reportDocument.SetParameterValue("FooterText", "Page ");
// Crystal Reports handles page numbers through formula fields
// configured in the designer
reportDocument.ExportToDisk(ExportFormatType.PortableDocFormat, "output.pdf");
reportDocument.Close();
reportDocument.Dispose();
}
}(IronPDF 之後):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
// Configure headers and footers
renderer.RenderingOptions.TextHeader.CenterText = "Company Name";
renderer.RenderingOptions.TextHeader.FontSize = 12;
renderer.RenderingOptions.TextFooter.LeftText = "Confidential";
renderer.RenderingOptions.TextFooter.RightText = "Page {page} of {total-pages}";
renderer.RenderingOptions.TextFooter.FontSize = 10;
string htmlContent = "<h1>Document Title</h1><p>Document content goes here.</p>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF with headers and footers created!");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
// Configure headers and footers
renderer.RenderingOptions.TextHeader.CenterText = "Company Name";
renderer.RenderingOptions.TextHeader.FontSize = 12;
renderer.RenderingOptions.TextFooter.LeftText = "Confidential";
renderer.RenderingOptions.TextFooter.RightText = "Page {page} of {total-pages}";
renderer.RenderingOptions.TextFooter.FontSize = 10;
string htmlContent = "<h1>Document Title</h1><p>Document content goes here.</p>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF with headers and footers created!");
}
}SAP Crystal Reports 需要對頁首和頁尾進行設計時配置。 您必須使用 Crystal Reports 設計器在.rpt檔案中設計頁首和頁尾,然後在執行時傳遞"HeaderText"和"FooterText"等參數值。頁碼必須透過設計器中的公式欄位進行配置。
IronPDF 提供透過TextHeader和TextFooter屬性進行程式化頁首/頁尾配置。 直接在程式碼中設定CenterText 、 LeftText 、 RightText和FontSize 。 頁碼使用{page}和{total-pages}佔位符-無需設計。
常見的移民問題
問題 1:.rpt 檔案轉換
SAP Crystal Reports:包含嵌入式佈局、資料和公式的二進位 .rpt 檔案。
解決方案:無法直接轉換-必須重新建立為 HTML:
- 在 Crystal Reports 設計器中開啟 .rpt 文件
- 文檔版面、字型、顏色
- 注意所有公式字段
- 用 HTML/CSS 重新建立
- 將公式轉換為 C# 程式碼
問題 2:資料庫連接
SAP Crystal Reports:嵌入式連線字串和 ODBC。
解決方案:使用應用程式的資料層:
// Instead of Crystal's database integration
var data = await _dbContext.Orders
.Where(o => o.Date >= startDate && o.Date <= endDate)
.ToListAsync();
// Bind to HTML template
var html = GenerateReportHtml(data);// Instead of Crystal's database integration
var data = await _dbContext.Orders
.Where(o => o.Date >= startDate && o.Date <= endDate)
.ToListAsync();
// Bind to HTML template
var html = GenerateReportHtml(data);問題 3:運行時依賴關係
SAP Crystal Reports:需要安裝 Crystal Reports Runtime(500MB+)。
解決方案: IronPDF 是獨立的:
# Just add the NuGet package
dotnet add package IronPdf
# That's it - no additional installs needed# Just add the NuGet package
dotnet add package IronPdf
# That's it - no additional installs needed問題 4:32 位元/64 位元問題
SAP Crystal Reports: COM 相依性通常需要 32 位元模式。
解決方案: IronPDF 是原生 64 位元版本-無需特殊配置。
遷移後的新功能
移轉到 IronPDF 後,您將獲得 SAP Crystal Reports 無法提供的功能:
PDF合併
var pdf1 = PdfDocument.FromFile("report1.pdf");
var pdf2 = PdfDocument.FromFile("report2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("complete_report.pdf");var pdf1 = PdfDocument.FromFile("report1.pdf");
var pdf2 = PdfDocument.FromFile("report2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("complete_report.pdf");PDF 安全性
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(reportHtml);
pdf.MetaData.Title = "Quarterly Sales Report";
pdf.MetaData.Author = "Finance Department";
pdf.SecuritySettings.OwnerPassword = "admin123";
pdf.SecuritySettings.UserPassword = "view123";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SaveAs("secure_report.pdf");var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(reportHtml);
pdf.MetaData.Title = "Quarterly Sales Report";
pdf.MetaData.Author = "Finance Department";
pdf.SecuritySettings.OwnerPassword = "admin123";
pdf.SecuritySettings.UserPassword = "view123";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SaveAs("secure_report.pdf");數位簽名
var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);水印
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>");pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>");功能對比總結
| 特徵 | SAP Crystal Reports | IronPDF |
|---|---|---|
| 安裝 | ||
| 運行時大小 | 500MB以上 | 約20MB |
| 安裝方法 | MSI/Setup.exe | NuGet |
| 部署 | 複雜的 | xcopy |
| 平台支援 | ||
| .NET框架 | 是的 | 是的 |
| .NET Core/5/6/7/8 | 有限的 | 滿的 |
| 64 位元原生 | 有問題的 | 是的 |
| Linux/Docker | 不 | 是的 |
| Azure/AWS | 難的 | 簡單的 |
| 發展 | ||
| 報表設計器 | 必需的 | 可選(HTML) |
| 範本格式 | .rpt(二進位) | HTML/CSS |
| 學習曲線 | 晶體語法 | 網路標準 |
| 智慧感知 | 不 | 完整的 C# |
| 渲染 | ||
| HTML 轉 PDF | 不 | 全鉻 |
| PDF檔案的URL | 不 | 是的 |
| CSS 支援 | 不 | 完整的 CSS3 |
| JavaScript | 不 | 完整版 ES2024 |
| PDF 功能 | ||
| 合併PDF | 不 | 是的 |
| 拆分PDF | 不 | 是的 |
| 水印 | 有限的 | 完整 HTML |
| 數位簽名 | 不 | 是的 |
| PDF/A | 不 | 是的 |
遷移清單
遷移前
- 清點所有
.rpt文件 - 截取每份報告版面的螢幕截圖以供參考
- 文檔公式欄位和計算 列出所有資料來源和參數
- 確定列印要求
- 從ironpdf.com取得 IronPDF 許可證金鑰
程式碼更新
- 移除 Crystal Reports 套件(
CrystalDecisions.CrystalReports.Engine等) - 從部署中移除執行時間安裝 安裝
IronPdfNuGet 套件 - 將
.rpt佈局轉換為 HTML/CSS 模板 - 將 Crystal 公式轉換為 C# 程式碼
- 將資料綁定從
SetDataSource()更新為 HTML 字串插值 - 將列印程式碼從
PrintToPrinter()更新為pdf.Print() - 在應用程式啟動時新增許可證初始化
基礎設施
從伺服器移除 Crystal Runtime
- 更新部署腳本
- 移除 32 位元相容模式
- 更新 Docker 映像(如適用)
測試
- 將 PDF 輸出與原始報告進行比較
- 核對所有計算結果。
- 測試所有參數
- 測試列印功能
- 效能測試
- 64 位元測試






