跳過到頁腳內容
遷移指南

如何用 C# 從 jsreport 轉移到 IronPDF

從jsreport轉換到 IronPDF,可將您的 .NET PDF 工作流程從一個依賴 Node.js 的系統(包含外部二進位管理和獨立的伺服器進程)轉變為一個完全在進程中執行的純 .NET 函式庫。 本指南提供了一個全面、循序漸進的遷移路徑,為專業的 .NET 開發人員消除基礎架構的複雜性和 JavaScript 模板的需求。

為什麼要從jsreport移轉到 IronPDF?

jsreport的挑戰

jsreport 引入了不屬於純 .NET 環境的複雜性:

  1. Node.js 依賴項:需要 Node.js 運行時和二進位文件,這給原本應該是一個簡單的 .NET 應用程式增加了基礎架構的複雜性。

2.外部二進位檔案管理:必須透過單獨的 NuGet 套件(jsreport.Binaryjsreport.Binary.Linuxjsreport.Binary.OSX)下載和管理 Windows、Linux 和 OSX 平台特定的二進位檔案。

3.獨立伺服器進程:作為實用程式或 Web 伺服器運作-需要使用 StartAsync()KillAsync() 生命週期方法進行額外的進程管理。

  1. JavaScript 模板:強制學習 Handlebars、JsRender 或其他 JavaScript 模板系統,而不是使用原生 C# 功能。

5.複雜的請求結構:即使是簡單的 PDF 生成,也需要詳細的 RenderRequest 物件以及嵌套的 Template 配置。

6.許可證限制:免費套餐限制範本數量; 縮放需要商業授權。

7.基於流的輸出:傳回需要手動文件操作和記憶體流管理的流。

jsreport與IronPDF的比較

特點 jsreport IronPDF
運行時間 Node.js + .NET 純 .NET
二進位管理 手冊 (jsreport.Binary 套件) 自動化
伺服器流程 必需 (公用程式或網路伺服器) 處理中
模板製作 JavaScript (Handlebars 等) C# (Razor、字串插值)
API 風格 繁複的請求物件 乾淨流暢的方法
輸出 PdfDocument 物件
PDF 操作 限額 廣泛(合併、分割、編輯)
同步支援 僅限同步 同步和同步

對於計劃在 2025 年和 2026 年之前採用 .NET 10 和 C# 14 的團隊而言,IronPDF 可作為原生 .NET 函式庫提供面向未來的基礎,而無需外部執行時依賴。


遷移複雜性評估

按功能估計的工作量

特點 遷移複雜性
HTML 至 PDF 非常低
URL 至 PDF 非常低
頁首/頁尾
頁面設定
伺服器生命週期
二進位管理

範式轉移

jsreport 遷移的根本轉變在於從冗長的請求物件(包含伺服器管理)轉變為簡單的進程內方法呼叫:

jsreport:  LocalReporting().UseBinary().AsUtility().Create() → RenderAsync(RenderRequest) →流→ File
IronPDF:   ChromePdfRenderer → RenderHtmlAsPdf(html) → SaveAs()

開始之前

先決條件

  1. .NET環境: .NET Framework 4.6.2+ 或.NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet存取權限:能夠安裝NuGet套件
  3. IronPDF許可證:請從IronPDF取得您的許可證密鑰。

NuGet 套件變更

# Removejsreportpackages
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
# Removejsreportpackages
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
SHELL

授權組態

// 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";
' Add at application startup (Program.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

辨識jsreport使用方式

# Find alljsreportreferences
grep -r "using jsreport\|LocalReporting\|RenderRequest\|RenderAsync" --include="*.cs" .
grep -r "JsReportBinary\|Template\|Recipe\|Engine\." --include="*.cs" .
# Find alljsreportreferences
grep -r "using jsreport\|LocalReporting\|RenderRequest\|RenderAsync" --include="*.cs" .
grep -r "JsReportBinary\|Template\|Recipe\|Engine\." --include="*.cs" .
SHELL

完整的 API 參考資料

類別對應

jsreport 類別 IronPDF 同等級產品
LocalReporting ChromePdfRenderer
ReportingService ChromePdfRenderer
RenderRequest 方法參數
Template 方法參數
Chrome RenderingOptions
Report PdfDocument
Engine (不需要)

方法對應

jsreport 方法 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

RenderRequest 屬性對應

jsreport 範本屬性 IronPDF 同等級產品
Template.Content 第一個參數給 RenderHtmlAsPdf()
Template.Recipe = Recipe.ChromePdf (不需要)
Template.Engine = Engine.None (不需要)
Chrome.HeaderTemplate RenderingOptions.TextHeaderHtmlHeader
Chrome.FooterTemplate RenderingOptions.TextFooterHtmlFooter
Chrome.DisplayHeaderFooter (自動)
Chrome.MarginTop RenderingOptions.MarginTop

占位符對應(頁首/頁腳)

jsreport 占位符 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!");
    }
}
Imports jsreport.Binary
Imports jsreport.Local
Imports jsreport.Types
Imports System
Imports System.IO
Imports System.Threading.Tasks

Module Program
    Async Function Main(args As String()) As Task
        Dim rs = (New LocalReporting()) _
            .UseBinary(JsReportBinary.GetBinary()) _
            .AsUtility() _
            .Create()

        Dim report = Await rs.RenderAsync(New RenderRequest() With {
            .Template = New Template() With {
                .Recipe = Recipe.ChromePdf,
                .Engine = Engine.None,
                .Content = "<h1>Hello from jsreport</h1><p>This is a PDF document.</p>"
            }
        })

        Using fileStream = File.Create("output.pdf")
            report.Content.CopyTo(fileStream)
        End Using

        Console.WriteLine("PDF created successfully!")
    End Function
End Module
$vbLabelText   $csharpLabel

After (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!");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main(args As String())
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello from IronPDF</h1><p>This is a PDF document.</p>")
        pdf.SaveAs("output.pdf")
        Console.WriteLine("PDF created successfully!")
    End Sub
End Class
$vbLabelText   $csharpLabel

jsreport 方法需要三個 NuGet 套件(jsreport.Binaryjsreport.Localjsreport.Types)、三個命名空間導入、僅異步執行、流暢的構建器鏈(@@--CODE-17830--@@)、包含巢狀 Template 對象的冗長 RenderRequest(指定了 RecipeEngine),以及使用 using 區塊手動將流複製到檔案。

IronPDF 可將其簡化為一個 NuGet 套件、一個命名空間、三行程式碼和同步執行。 ChromePdfRenderer.RenderHtmlAsPdf() 方法直接接受 HTML,並傳回一個 PdfDocument,其中包含一個簡單的 SaveAs() 方法。 請參閱 HTML to PDF 文件,以瞭解其他渲染選項。

範例 2:URL 至 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 = "<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!");
    }
}
Imports jsreport.Binary
Imports jsreport.Local
Imports jsreport.Types
Imports System
Imports System.IO
Imports System.Threading.Tasks

Module Program
    Async Function Main(args As String()) As Task
        Dim rs = (New LocalReporting()) _
            .UseBinary(JsReportBinary.GetBinary()) _
            .AsUtility() _
            .Create()

        Dim report = Await rs.RenderAsync(New RenderRequest() With {
            .Template = New Template() With {
                .Recipe = Recipe.ChromePdf,
                .Engine = Engine.None,
                .Content = "<html><body><script>window.location='https://example.com';</script></body></html>"
            }
        })

        Using fileStream = File.Create("webpage.pdf")
            report.Content.CopyTo(fileStream)
        End Using

        Console.WriteLine("Webpage PDF created successfully!")
    End Function
End Module
$vbLabelText   $csharpLabel

After (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!");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main(ByVal args As String())
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
        pdf.SaveAs("webpage.pdf")
        Console.WriteLine("Webpage PDF created successfully!")
    End Sub
End Class
$vbLabelText   $csharpLabel

此範例突顯了jsreport的一大限制:沒有直接的 URL 轉 PDF 方法。jsreport程式碼必須使用嵌入在 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!");
    }
}
Imports jsreport.Binary
Imports jsreport.Local
Imports jsreport.Types
Imports System
Imports System.IO
Imports System.Threading.Tasks

Module Program
    Async Function Main(args As String()) As Task
        Dim rs = New LocalReporting() _
            .UseBinary(JsReportBinary.GetBinary()) _
            .AsUtility() _
            .Create()

        Dim report = Await rs.RenderAsync(New RenderRequest() With {
            .Template = New Template() With {
                .Recipe = Recipe.ChromePdf,
                .Engine = Engine.None,
                .Content = "<h1>Document with Header and Footer</h1><p>Main content goes here.</p>",
                .Chrome = New Chrome() With {
                    .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 fileStream = File.Create("document_with_headers.pdf")
            report.Content.CopyTo(fileStream)
        End Using

        Console.WriteLine("PDF with headers and footers created successfully!")
    End Function
End Module
$vbLabelText   $csharpLabel

After (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!");
    }
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System

Module Program
    Sub Main(args As String())
        Dim renderer As New ChromePdfRenderer()
        renderer.RenderingOptions.TextHeader = New TextHeaderFooter() With {
            .CenterText = "Custom Header",
            .FontSize = 10
        }
        renderer.RenderingOptions.TextFooter = New TextHeaderFooter() With {
            .CenterText = "Page {page} of {total-pages}",
            .FontSize = 10
        }

        Dim 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!")
    End Sub
End Module
$vbLabelText   $csharpLabel

jsreport。 頁頭與頁尾的範本必須包含完整的內嵌式樣。

IronPDF 提供更簡潔的 TextHeaderFooter 配置,並為 CenterTextLeftTextRightTextFontSize--CODE-17849--@@ 和 FontSize 提供專用屬性。 頁碼佔位符使用較簡單的 {page}{total-pages} 語法。 有關 HTML 標頭選項,請參閱 標頭與頁尾文件


關鍵遷移注意事項

消除伺服器生命週期管理

jsreport 需要明確的伺服器生命週期管理:

//jsreport(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();
//jsreport(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();
'jsreport(DELETE THIS):
Dim rs = New LocalReporting() _
    .UseBinary(JsReportBinary.GetBinary()) _
    .AsUtility() _
    .Create()

' Or for web server mode:
rs = New LocalReporting() _
    .UseBinary(JsReportBinary.GetBinary()) _
    .AsWebServer() _
    .Create()

Await rs.StartAsync()
' ... use rs ...
Await rs.KillAsync()
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

移除特定平台的二進位套件

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.OSX
SHELL

IronPDF 可透過單一 NuGet 套件自動處理所有平台需求。

更新占位符語法

jsreport 使用 CSS 類別型或大括弧占位符。IronPDF使用不同的語法:

//jsreportplaceholders:
"<span class='pageNumber'></span>"  // or {#pageNum}
"<span class='totalPages'></span>"  // or {#numPages}

//IronPDFplaceholders:
"{page}"
"{total-pages}"
"{date}"
"{html-title}"
//jsreportplaceholders:
"<span class='pageNumber'></span>"  // or {#pageNum}
"<span class='totalPages'></span>"  // or {#numPages}

//IronPDFplaceholders:
"{page}"
"{total-pages}"
"{date}"
"{html-title}"
'jsreportplaceholders:
"<span class='pageNumber'></span>"  ' or {#pageNum}
"<span class='totalPages'></span>"  ' or {#numPages}

'IronPDFplaceholders:
"{page}"
"{total-pages}"
"{date}"
"{html-title}"
$vbLabelText   $csharpLabel

使用 C# 字串插值取代手把手

jsreport 通常使用 Handlebars 模板,程式碼如下:Engine.Handlebars:

//jsreportHandlebars (DELETE THIS):
Template = new Template
{
    Content = "<h1>Hello, {{name}}</h1>",
    Engine = Engine.Handlebars
},
Data = new { name = "World" }

//IronPDFwith C# string interpolation:
string name = "World";
string html = $"<h1>Hello, {name}</h1>";
var pdf = renderer.RenderHtmlAsPdf(html);
//jsreportHandlebars (DELETE THIS):
Template = new Template
{
    Content = "<h1>Hello, {{name}}</h1>",
    Engine = Engine.Handlebars
},
Data = new { name = "World" }

//IronPDFwith C# string interpolation:
string name = "World";
string html = $"<h1>Hello, {name}</h1>";
var pdf = renderer.RenderHtmlAsPdf(html);
Imports IronPdf

' jsreportHandlebars (DELETE THIS):
Dim template As New Template With {
    .Content = "<h1>Hello, {{name}}</h1>",
    .Engine = Engine.Handlebars
}

Dim data = New With {.name = "World"}

' IronPDF with VB.NET string interpolation:
Dim name As String = "World"
Dim html As String = $"<h1>Hello, {name}</h1>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

簡化串流處理

jsreport 會返回一個需要手動複製的串流:

//jsreportstream 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();
}

//IronPDFdirect access:
pdf.SaveAs("output.pdf");
// Or:
byte[] bytes = pdf.BinaryData;
//jsreportstream 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();
}

//IronPDFdirect access:
pdf.SaveAs("output.pdf");
// Or:
byte[] bytes = pdf.BinaryData;
Imports System.IO

'jsreportstream handling (DELETE THIS):
Using fileStream As FileStream = File.Create("output.pdf")
    report.Content.CopyTo(fileStream)
End Using

' Or for byte array:
Using memoryStream As New MemoryStream()
    Await report.Content.CopyToAsync(memoryStream)
    Return memoryStream.ToArray()
End Using

'IronPDFdirect access:
pdf.SaveAs("output.pdf")
' Or:
Dim bytes As Byte() = pdf.BinaryData
$vbLabelText   $csharpLabel

疑難排解

問題 1:LocalReporting 未找到

問題:程式碼引用了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();
' jsreport
Dim rs = New LocalReporting().UseBinary().AsUtility().Create()

' IronPDF
Dim renderer = New ChromePdfRenderer()
$vbLabelText   $csharpLabel

問題 2:未找到 RenderRequest

問題:程式碼使用了 RenderRequestTemplate 包裝物件。

解決方案:直接將 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);
Imports System.Threading.Tasks

' jsreport
Await rs.RenderAsync(New RenderRequest With {.Template = New Template With {.Content = html}})

' IronPDF
Dim pdf = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

問題 3:未顯示頁碼

問題:使用jsreport佔位語法 <span class='pageNumber'></span>

解決方案:更新IronPDF佔位符語法:

//jsreportsyntax (won't work)
"Page <span class='pageNumber'></span> of <span class='totalPages'></span>"

//IronPDFsyntax
"Page {page} of {total-pages}"
//jsreportsyntax (won't work)
"Page <span class='pageNumber'></span> of <span class='totalPages'></span>"

//IronPDFsyntax
"Page {page} of {total-pages}"
'jsreportsyntax (won't work)
"Page <span class='pageNumber'></span> of <span class='totalPages'></span>"

'IronPDFsyntax
"Page {page} of {total-pages}"
$vbLabelText   $csharpLabel

問題 4:未找到 JsReportBinary

問題:代碼引用了 JsReportBinary.GetBinary()

解決方案:完全刪除-IronPDF 不需要外部二進位檔案:

// DELETE thisjsreportpattern:
.UseBinary(JsReportBinary.GetBinary())

//IronPDFneeds nothing—just create the renderer:
var renderer = new ChromePdfRenderer();
// DELETE thisjsreportpattern:
.UseBinary(JsReportBinary.GetBinary())

//IronPDFneeds nothing—just create the renderer:
var renderer = new ChromePdfRenderer();
$vbLabelText   $csharpLabel

遷移清單

預遷移

  • 辨識所有jsreportusing 語句
  • 使用 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() 調用
  • 將流複製替換為 BinaryDataSaveAs()

測試

  • 測試所有 PDF 生成路徑
  • 驗證頁首/頁尾渲染效果 檢查頁碼
  • 驗證邊距間距
  • 使用複雜的 CSS/JavaScript 頁面進行測試
  • 基準性能

後遷移

  • 刪除jsreport二進位文件
  • 如果不再需要,請移除 Node.js 依賴項
  • 更新部署腳本
  • 更新文件

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我