如何在 C# 中將 jsreport 遷移到 IronPDF
從 js報告 遷移到 IronPDF 會將您的 .NET PDF 工作流程從一個依賴 Node.js 的系統(具有外部二進位管理和單獨的伺服器進程)轉變為完全在進程內運行的純 .NET 程式庫。 本指南提供了一個全面的、循序漸進的遷移路徑,消除了專業 .NET 開發人員的基礎架構複雜性和 JavaScript 模板要求。
為什麼要從 js報告 遷移到 IronPDF
js報告 的挑戰
jsreport 引入了純 .NET 環境中不應該存在的複雜性:
- Node.js 依賴項:需要 Node.js 運行時和二進位文件,這給原本應該是一個簡單的 .NET 應用程式增加了基礎架構的複雜性。
2.外部二進位檔案管理:必須透過單獨的 NuGet 套件( jsreport.Binary 、 jsreport.Binary.Linux 、 jsreport.Binary.OSX )下載和管理 Windows、Linux 和 OSX 平台特定的二進位檔案。
3.獨立伺服器進程:作為實用程式或 Web 伺服器運作-需要使用StartAsync()和KillAsync()生命週期方法進行額外的進程管理。
- JavaScript 模板:強制學習 Handlebars、JsRender 或其他 JavaScript 模板系統,而不是使用原生 C# 功能。
5.複雜的請求結構:即使是簡單的 PDF 生成,也需要詳細的RenderRequest物件以及嵌套的Template配置。
6.許可證限制:免費套餐限制範本數量; 擴展規模需要商業許可。
7.基於流的輸出:傳回需要手動文件操作和記憶體流管理的流。
js報告 與 IronPDF 的比較
| 特徵 | js報告 | IronPDF |
|---|---|---|
| 運行時 | Node.js + .NET | 純.NET |
| 二進位管理 | 手動(jsreport.二進位包) | 自動的 |
| 伺服器進程 | 必需(實用程式或 Web 伺服器) | 進行中 |
| 範本 | JavaScript(Handlebars 等) | C#(Razor,字串插值) |
| API 風格 | 詳細請求對象 | 清潔流暢的方法 |
| 輸出 | 溪流 | PdfDocument 對象 |
| PDF 處理 | 有限的 | 廣泛的(合併、拆分、編輯) |
| 非同步支援 | 僅異步 | 同步和非同步 |
對於計畫在 2025 年和 2026 年採用 .NET 10 和 C# 14 的團隊而言,IronPDF 提供了一個面向未來的基礎,它是一個原生 .NET 函式庫,沒有外部執行時間依賴項。
遷移複雜度評估
各功能預計工作量
| 特徵 | 遷移複雜性 | 筆記 |
|---|---|---|
| HTML 轉 PDF | 非常低 | 直接替代法 |
| PDF檔案的URL | 非常低 | 直接方法,無需變通 |
| 頁首/頁尾 | 低的 | 佔位符語法更改 |
| 頁面設定 | 低的 | 屬性映射 |
| 伺服器生命週期 | 低的 | 完全刪除 |
| 二進位管理 | 低的 | 完全刪除 |
範式轉移
jsreport 遷移的根本轉變在於從冗長的請求物件(包含伺服器管理)轉變為簡單的進程內方法呼叫:
jsreport:LocalReporting().UseBinary().AsUtility().Create() → RenderAsync(RenderRequest) → 溪流 → File
IronPDF:ChromePdfRenderer → RenderHtmlAsPdf(html) → SaveAs()開始之前
先決條件
- .NET 環境: .NET Framework 4.6.2+ 或 .NET Core 3.1+ / .NET 5/6/7/8/9+
- NuGet 存取權限:能夠安裝 NuGet 套件
- IronPDF 許可證:請從ironpdf.com取得您的許可證密鑰。
NuGet 套件變更
# Remove js報告 packages
dotnet remove package jsreport.Binary
dotnet remove package jsreport.Binary.Linux
dotnet remove package jsreport.Binary.OSX
dotnet remove package jsreport.Local
dotnet remove package jsreport.Types
dotnet remove package jsreport.Client
# Install IronPDF
dotnet add package IronPdf# Remove js報告 packages
dotnet remove package jsreport.Binary
dotnet remove package jsreport.Binary.Linux
dotnet remove package jsreport.Binary.OSX
dotnet remove package jsreport.Local
dotnet remove package jsreport.Types
dotnet remove package jsreport.Client
# Install IronPDF
dotnet add package IronPdf許可證配置
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";辨識 js報告 的使用情況
# Find all js報告 references
grep -r "using jsreport\|LocalReporting\|RenderRequest\|RenderAsync" --include="*.cs" .
grep -r "JsReportBinary\|Template\|Recipe\|Engine\." --include="*.cs" .# Find all js報告 references
grep -r "using jsreport\|LocalReporting\|RenderRequest\|RenderAsync" --include="*.cs" .
grep -r "JsReportBinary\|Template\|Recipe\|Engine\." --include="*.cs" .完整 API 參考
類別映射
| js報告 類別 | IronPDF當量 | 筆記 |
|---|---|---|
LocalReporting | ChromePdfRenderer | 主渲染器 |
ReportingService | ChromePdfRenderer | 同級 |
RenderRequest | 方法參數 | 無需包裝 |
Template | 方法參數 | 無需包裝 |
Chrome | RenderingOptions | Chrome 選項 |
Report | PdfDocument | 結果對象 |
Engine | (不需要) | C# 用於模板 |
方法映射
| js報告 方法 | IronPDF當量 | 筆記 |
|---|---|---|
LocalReporting().UseBinary().AsUtility().Create() | new ChromePdfRenderer() | 一句話 |
rs.RenderAsync(request) | renderer.RenderHtmlAsPdf(html) | 直接通話 |
rs.StartAsync() | (不需要) | 進行中 |
rs.KillAsync() | (不需要) | 自動清潔 |
report.Content.CopyTo(stream) | pdf.SaveAs(path)或pdf.BinaryData | 直接訪問 |
渲染請求屬性映射
| js報告 範本屬性 | IronPDF當量 | 筆記 |
|---|---|---|
Template.Content | RenderHtmlAsPdf()函數的第一個參數 | 直接 HTML 字串 |
Template.Recipe = Recipe.ChromePdf | (不需要) | 始終 ChromePDF |
Template.Engine = Engine.None | (不需要) | 使用 C# 模板 |
Chrome.HeaderTemplate | RenderingOptions.TextHeader或HtmlHeader | HTML 頭部 |
Chrome.FooterTemplate | RenderingOptions.TextFooter或HtmlFooter | HTML頁腳 |
Chrome.DisplayHeaderFooter | (自動的) | 自動啟用標頭 |
Chrome.MarginTop | RenderingOptions.MarginTop | 單位:毫米 |
佔位符映射(頁首/頁尾)
| js報告佔位符 | IronPDF佔位符 | 筆記 |
|---|---|---|
<span> class="pageNumber"></span> | {page} | 目前頁面 |
<span> class="totalPages"></span> | {total-pages} | 總頁數 |
{#pageNum} | {page} | 目前頁面 |
{#numPages} | {total-pages} | 總頁數 |
{#timestamp} | {date} | 目前日期 |
程式碼遷移範例
範例 1:基本 HTML 轉 PDF
前(jsreport):
// NuGet: Install-Package jsreport.Binary
// NuGet: Install-Package jsreport.Local
// NuGet: Install-Package jsreport.Types
using jsreport.Binary;
using jsreport.Local;
using jsreport.Types;
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsUtility()
.Create();
var report = await rs.RenderAsync(new RenderRequest()
{
Template = new Template()
{
Recipe = Recipe.ChromePdf,
Engine = Engine.None,
Content = "<h1>Hello from jsreport</h1><p>This is a PDF document.</p>"
}
});
using (var fileStream = File.Create("output.pdf"))
{
report.Content.CopyTo(fileStream);
}
Console.WriteLine("PDF created successfully!");
}
}// NuGet: Install-Package jsreport.Binary
// NuGet: Install-Package jsreport.Local
// NuGet: Install-Package jsreport.Types
using jsreport.Binary;
using jsreport.Local;
using jsreport.Types;
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsUtility()
.Create();
var report = await rs.RenderAsync(new RenderRequest()
{
Template = new Template()
{
Recipe = Recipe.ChromePdf,
Engine = Engine.None,
Content = "<h1>Hello from jsreport</h1><p>This is a PDF document.</p>"
}
});
using (var fileStream = File.Create("output.pdf"))
{
report.Content.CopyTo(fileStream);
}
Console.WriteLine("PDF created successfully!");
}
}(IronPDF 之後):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello from IronPDF</h1><p>This is a PDF document.</p>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully!");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello from IronPDF</h1><p>This is a PDF document.</p>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully!");
}
}jsreport 方法需要三個 NuGet 套件( jsreport.Binary 、 jsreport.Local 、 jsreport.Types )、三個命名空間導入、僅異步執行Recipe流暢的建構Template鏈( LocalReporting().UseBinary().AsUtility().Create() RenderRequest using Engine using塊手動將流複製到檔案。
IronPDF 將此簡化為一個 NuGet 套件、一個命名空間、三行程式碼和同步執行。 ChromePdfRenderer.RenderHtmlAsPdf()方法直接接受 HTML 並傳回一個帶有簡單SaveAs()方法的PdfDocument 。 有關其他渲染選項,請參閱HTML 轉 PDF 文件。
範例 2:PDF 的 URL
前(jsreport):
// NuGet: Install-Package jsreport.Binary
// NuGet: Install-Package jsreport.Local
// NuGet: Install-Package jsreport.Types
using jsreport.Binary;
using jsreport.Local;
using jsreport.Types;
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsUtility()
.Create();
var report = await rs.RenderAsync(new RenderRequest()
{
Template = new Template()
{
Recipe = Recipe.ChromePdf,
Engine = Engine.None,
Content = "<html><body><script>window.location='https://example.com';</script></body></html>"
}
});
using (var fileStream = File.Create("webpage.pdf"))
{
report.Content.CopyTo(fileStream);
}
Console.WriteLine("Webpage PDF created successfully!");
}
}// NuGet: Install-Package jsreport.Binary
// NuGet: Install-Package jsreport.Local
// NuGet: Install-Package jsreport.Types
using jsreport.Binary;
using jsreport.Local;
using jsreport.Types;
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsUtility()
.Create();
var report = await rs.RenderAsync(new RenderRequest()
{
Template = new Template()
{
Recipe = Recipe.ChromePdf,
Engine = Engine.None,
Content = "<html><body><script>window.location='https://example.com';</script></body></html>"
}
});
using (var fileStream = File.Create("webpage.pdf"))
{
report.Content.CopyTo(fileStream);
}
Console.WriteLine("Webpage PDF created successfully!");
}
}(IronPDF 之後):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("Webpage PDF created successfully!");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("Webpage PDF created successfully!");
}
}這個例子突顯了 js報告 的一個重大限制:沒有直接的 URL 轉 PDF 方法。 js報告 程式碼必須使用嵌入在 HTML 內容中的 JavaScript 重定向變通方法( window.location='https://example.com' )來擷取網頁。 這種間接方法在某些網站上可能無效,並且會增加不必要的複雜性。
IronPDF 提供了一個專門的RenderUrlAsPdf()方法,可以直接渲染任何 URL,並完全執行 JavaScript 操作,支援現代 CSS。 無需任何變通方法,無需嵌入腳本——只需傳遞 URL 即可。 了解更多關於URL轉PDF的資訊。
範例 3:帶有頁首和頁尾的 PDF
前(jsreport):
// NuGet: Install-Package jsreport.Binary
// NuGet: Install-Package jsreport.Local
// NuGet: Install-Package jsreport.Types
using jsreport.Binary;
using jsreport.Local;
using jsreport.Types;
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsUtility()
.Create();
var report = await rs.RenderAsync(new RenderRequest()
{
Template = new Template()
{
Recipe = Recipe.ChromePdf,
Engine = Engine.None,
Content = "<h1>Document with Header and Footer</h1><p>Main content goes here.</p>",
Chrome = new Chrome()
{
DisplayHeaderFooter = true,
HeaderTemplate = "<div style='font-size:10px; text-align:center; width:100%;'>Custom Header</div>",
FooterTemplate = "<div style='font-size:10px; text-align:center; width:100%;'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></div>"
}
}
});
using (var fileStream = File.Create("document_with_headers.pdf"))
{
report.Content.CopyTo(fileStream);
}
Console.WriteLine("PDF with headers and footers created successfully!");
}
}// NuGet: Install-Package jsreport.Binary
// NuGet: Install-Package jsreport.Local
// NuGet: Install-Package jsreport.Types
using jsreport.Binary;
using jsreport.Local;
using jsreport.Types;
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsUtility()
.Create();
var report = await rs.RenderAsync(new RenderRequest()
{
Template = new Template()
{
Recipe = Recipe.ChromePdf,
Engine = Engine.None,
Content = "<h1>Document with Header and Footer</h1><p>Main content goes here.</p>",
Chrome = new Chrome()
{
DisplayHeaderFooter = true,
HeaderTemplate = "<div style='font-size:10px; text-align:center; width:100%;'>Custom Header</div>",
FooterTemplate = "<div style='font-size:10px; text-align:center; width:100%;'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></div>"
}
}
});
using (var fileStream = File.Create("document_with_headers.pdf"))
{
report.Content.CopyTo(fileStream);
}
Console.WriteLine("PDF with headers and footers created successfully!");
}
}(IronPDF 之後):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
CenterText = "Custom Header",
FontSize = 10
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10
};
var pdf = renderer.RenderHtmlAsPdf("<h1>Document with Header and Footer</h1><p>Main content goes here.</p>");
pdf.SaveAs("document_with_headers.pdf");
Console.WriteLine("PDF with headers and footers created successfully!");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
CenterText = "Custom Header",
FontSize = 10
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10
};
var pdf = renderer.RenderHtmlAsPdf("<h1>Document with Header and Footer</h1><p>Main content goes here.</p>");
pdf.SaveAs("document_with_headers.pdf");
Console.WriteLine("PDF with headers and footers created successfully!");
}
}jsreport 方法需要在Template中添加一個Chrome對象,設定DisplayHeaderFooter = true ,並使用帶有特殊 CSS 類別佔位符的 HTML 模板(<span> class="pageNumber"></span> ,<span> class="totalPages"></span> )。 頁首和頁尾範本必須包含完整的內嵌樣式。
IronPDF 提供了一個更簡潔的TextHeaderFooter配置,其中包含CenterText 、 LeftText 、 RightText和FontSize的專用屬性。 頁碼佔位符使用更簡單的{page}和{total-pages}語法。 有關 HTML 頭部選項,請參閱頭部和尾部文件。
關鍵遷移說明
取消伺服器生命週期管理
jsreport 需要明確的伺服器生命週期管理:
// js報告 (DELETE THIS):
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsUtility()
.Create();
// Or for web server mode:
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsWebServer()
.Create();
await rs.StartAsync();
// ... use rs ...
await rs.KillAsync();// js報告 (DELETE THIS):
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsUtility()
.Create();
// Or for web server mode:
var rs = new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsWebServer()
.Create();
await rs.StartAsync();
// ... use rs ...
await rs.KillAsync();IronPDF 完全在進程內運行——無需伺服器啟動、無需進程管理、無需清理:
// IronPDF:
var renderer = new ChromePdfRenderer();
// Just use it—no lifecycle management needed// IronPDF:
var renderer = new ChromePdfRenderer();
// Just use it—no lifecycle management needed移除平台特定的二進位軟體包
jsreport 需要為每個目標平台單獨安裝 NuGet 套件:
# DELETE these platform-specific packages:
dotnet remove package jsreport.Binary
dotnet remove package jsreport.Binary.Linux
dotnet remove package jsreport.Binary.OSX# DELETE these platform-specific packages:
dotnet remove package jsreport.Binary
dotnet remove package jsreport.Binary.Linux
dotnet remove package jsreport.Binary.OSXIronPDF 透過單一 NuGet 套件自動處理所有平台要求。
更新佔位符語法
jsreport 使用基於 CSS 類別或花括號的佔位符。 IronPDF 使用不同的語法:
// js報告 placeholders:
"<span class='pageNumber'></span>" // or {#pageNum}
"<span class='totalPages'></span>" // or {#numPages}
// IronPDF placeholders:
"{page}"
"{total-pages}"
"{date}"
"{html-title}"// js報告 placeholders:
"<span class='pageNumber'></span>" // or {#pageNum}
"<span class='totalPages'></span>" // or {#numPages}
// IronPDF placeholders:
"{page}"
"{total-pages}"
"{date}"
"{html-title}"用 C# 字串插值取代 Handlebars
jsreport 通常使用 Handlebars 模板引擎,並整合了Engine.Handlebars :
// js報告 Handlebars (DELETE THIS):
Template = new Template
{
Content = "<h1>Hello, {{name}}</h1>",
Engine = Engine.Handlebars
},
Data = new { name = "World" }
// IronPDF with C# string interpolation:
string name = "World";
string html = $"<h1>Hello, {name}</h1>";
var pdf = renderer.RenderHtmlAsPdf(html);// js報告 Handlebars (DELETE THIS):
Template = new Template
{
Content = "<h1>Hello, {{name}}</h1>",
Engine = Engine.Handlebars
},
Data = new { name = "World" }
// IronPDF with C# string interpolation:
string name = "World";
string html = $"<h1>Hello, {name}</h1>";
var pdf = renderer.RenderHtmlAsPdf(html);簡化流程處理
jsreport 傳回一個需要手動複製的資料流:
// js報告 stream handling (DELETE THIS):
using (var fileStream = File.Create("output.pdf"))
{
report.Content.CopyTo(fileStream);
}
// Or for byte array:
using (var memoryStream = new MemoryStream())
{
await report.Content.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
// IronPDF direct access:
pdf.SaveAs("output.pdf");
// Or:
byte[] bytes = pdf.BinaryData;// js報告 stream handling (DELETE THIS):
using (var fileStream = File.Create("output.pdf"))
{
report.Content.CopyTo(fileStream);
}
// Or for byte array:
using (var memoryStream = new MemoryStream())
{
await report.Content.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
// IronPDF direct access:
pdf.SaveAs("output.pdf");
// Or:
byte[] bytes = pdf.BinaryData;故障排除
問題 1:未找到本地報告
問題:程式碼引用了IronPDF中不存在的LocalReporting類別。
解決方案:替換為ChromePdfRenderer :
// jsreport
var rs = new LocalReporting().UseBinary().AsUtility().Create();
// IronPDF
var renderer = new ChromePdfRenderer();// jsreport
var rs = new LocalReporting().UseBinary().AsUtility().Create();
// IronPDF
var renderer = new ChromePdfRenderer();問題 2:找不到渲染請求
問題:程式碼使用了RenderRequest和Template包裝物件。
解決方案:直接將 HTML 傳遞給渲染方法:
// jsreport
await rs.RenderAsync(new RenderRequest { Template = new Template { Content = html } });
// IronPDF
var pdf = renderer.RenderHtmlAsPdf(html);// jsreport
await rs.RenderAsync(new RenderRequest { Template = new Template { Content = html } });
// IronPDF
var pdf = renderer.RenderHtmlAsPdf(html);問題3:頁碼不顯示
問題:使用 js報告 佔位語法<span> class="pageNumber"></span>。
解決方案:更新 IronPDF 佔位符語法:
// js報告 syntax (won't work)
"Page <span class='pageNumber'></span> of <span class='totalPages'></span>"
// IronPDF syntax
"Page {page} of {total-pages}"// js報告 syntax (won't work)
"Page <span class='pageNumber'></span> of <span class='totalPages'></span>"
// IronPDF syntax
"Page {page} of {total-pages}"問題 4:未找到 JsReportBinary
問題:程式碼引用了JsReportBinary.GetBinary() 。
解決方案:完全刪除-IronPDF 不需要外部二進位檔案:
// DELETE this js報告 pattern:
.UseBinary(JsReportBinary.GetBinary())
// IronPDF needs nothing—just create the renderer:
var renderer = new ChromePdfRenderer();// DELETE this js報告 pattern:
.UseBinary(JsReportBinary.GetBinary())
// IronPDF needs nothing—just create the renderer:
var renderer = new ChromePdfRenderer();遷移清單
遷移前
- 辨識所有
using語句的 jsreport - 使用 Handlebars/JsRender 的列表模板(轉換為 C# 字串插值)
- 記錄目前使用的 Chrome 設定選項(頁邊距、紙張大小)
- 檢查是 Web 伺服器模式還是實用程式模式(兩者都會進入進程內執行)
- 注意平台特定的二進位軟體套件(全部刪除)
- 取得 IronPDF 許可證密鑰
軟體包變更
- 刪除
jsreport.Binary包 - 刪除
jsreport.Binary.Linux軟體包 - 刪除
jsreport.Binary.OSX包 - 移除
jsreport.Local包 - 移除
jsreport.Types包 - 刪除
jsreport.Client包 安裝IronPdf包
程式碼更改
- 在啟動時新增許可證金鑰配置
- 將
LocalReporting替換為ChromePdfRenderer - 移除
RenderRequest包裝器 - 移除
Template包裝器 - 更新佔位符語法(
<span> class="pageNumber">→{page}) - 將 Handlebars 替換為 C# 字串插值
- 移除
StartAsync()/KillAsync()調用 - 將流複製替換為
BinaryData或SaveAs()
測試
- 測試所有 PDF 生成路徑
- 驗證頁首/頁尾渲染效果 檢查頁碼
- 驗證邊距間距
- 使用複雜的 CSS/JavaScript 頁面進行測試
- 基準性能
移民後
- 刪除 js報告 二進位文件
- 如果不再需要,請移除 Node.js 依賴項
- 更新部署腳本
- 更新文檔






