Como migrar do jsreport para o IronPDF em C#
A migração do jsreport para o IronPDF transforma seu fluxo de trabalho de PDF em .NET , de um sistema dependente de Node.js com gerenciamento de binários externos e processos de servidor separados, para uma biblioteca .NET pura que é executada inteiramente no mesmo processo. Este guia fornece um caminho de migração abrangente, passo a passo, que elimina a complexidade da infraestrutura e os requisitos de modelos JavaScript para desenvolvedores .NET profissionais.
Por que migrar do jsreport para o IronPDF?
Os desafios do jsreport
O jsreport introduz uma complexidade que não pertence a um ambiente .NET puro:
-
Dependência do Node.js : Requer o ambiente de execução e os binários do Node.js , adicionando complexidade à infraestrutura do que deveria ser uma aplicação .NET simples.
-
Gerenciamento de binários externos: É necessário baixar e gerenciar binários específicos da plataforma para Windows, Linux e OSX por meio de pacotes NuGet separados (
jsreport.Binary,jsreport.Binary.Linux,jsreport.Binary.OSX). -
Processo de servidor separado: Executa como um utilitário ou servidor web — gerenciamento de processo adicional é necessário com os métodos de ciclo de vida
StartAsync()eKillAsync(). -
Modelagem em JavaScript : Força o aprendizado de Handlebars, JsRender ou outros sistemas de modelagem em JavaScript em vez de usar os recursos nativos do C#.
-
Estrutura de solicitação complexa: Requer objetos verbosos
RenderRequestcom configurações aninhadasTemplateaté mesmo para geração simples de PDF. -
Limitações de licenciamento: O plano gratuito limita a quantidade de modelos; A escalabilidade requer licença comercial.
- Saída baseada em fluxo: Retorna fluxos que exigem operações manuais em arquivos e gerenciamento de fluxos de memória.
Comparação entre jsreport e IronPDF
| Recurso | jsreport | IronPDF |
|---|---|---|
| Tempo de execução | Node.js + .NET | .NET puro |
| Gerenciamento Binário | Manual (pacotes jsreport.Binary) | Automático |
| Processo do servidor | Requerido (servidor utilitário ou web) | Em andamento |
| Modelagem | JavaScript (Handlebars, etc.) | C# (Razor, interpolação de strings) |
| Estilo API | Objetos de solicitação detalhados | Métodos limpos e fluentes |
| Saída | Fluxo | Objeto PdfDocument |
| Manipulação de PDF | Limitado | Extenso (mesclar, dividir, editar) |
| Suporte assíncrono | Somente assíncrono | Tanto síncrono quanto assíncrono |
Para equipes que planejam a adoção do .NET 10 e do C# 14 até 2025 e 2026, o IronPDF oferece uma base preparada para o futuro como uma biblioteca .NET nativa, sem dependências externas de tempo de execução.
Avaliação da Complexidade da Migração
Esforço estimado por funcionalidade
| Recurso | Complexidade da Migração |
|---|---|
| HTML para PDF | Muito baixo |
| URL para PDF | Muito baixo |
| Cabeçalhos/Rodapés | Baixo |
| Configurações da página | Baixo |
| Ciclo de vida do servidor | Baixo |
| Gerenciamento Binário | Baixo |
Mudança de paradigma
A mudança fundamental nesta migração do jsreport é a substituição de objetos de requisição verbosos com gerenciamento de servidor por chamadas de método simples em processo:
jsreport: LocalReporting().UseBinary().AsUtility().Create() → RenderAsync(RenderRequest) → Fluxo → File
IronPDF: ChromePdfRenderer → RenderHtmlAsPdf(html) → SaveAs()
Antes de começar
Pré-requisitos
- Ambiente .NET : .NET Framework 4.6.2+ ou .NET Core 3.1+ / .NET 5/6/7/8/9+
- Acesso ao NuGet : Capacidade de instalar pacotes NuGet.
- Licença do IronPDF : Obtenha sua chave de licença em IronPDF
Alterações no pacote NuGet
# Remove jsreport 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 jsreport 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
Configuração de licença
// 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"
Identificar o uso do jsreport
# Find all jsreport references
grep -r "using jsreport\|LocalReporting\|RenderRequest\|RenderAsync" --include="*.cs" .
grep -r "JsReportBinary\|Template\|Recipe\|Engine\." --include="*.cs" .
# Find all jsreport references
grep -r "using jsreport\|LocalReporting\|RenderRequest\|RenderAsync" --include="*.cs" .
grep -r "JsReportBinary\|Template\|Recipe\|Engine\." --include="*.cs" .
Referência completa da API
Mapeamentos de Classes
| Classe jsreport | Equivalente ao IronPDF |
|---|---|
LocalReporting |
ChromePdfRenderer |
ReportingService |
ChromePdfRenderer |
RenderRequest |
Parâmetros do método |
Template |
Parâmetros do método |
Chrome |
RenderingOptions |
Report |
PdfDocument |
Engine |
(não é necessário) |
Mapeamentos de Métodos
| Método jsreport | Equivalente ao IronPDF |
|---|---|
LocalReporting().UseBinary().AsUtility().Create() |
new ChromePdfRenderer() |
rs.RenderAsync(request) |
renderer.RenderHtmlAsPdf(html) |
rs.StartAsync() |
(não é necessário) |
rs.KillAsync() |
(não é necessário) |
report.Content.CopyTo(stream) |
pdf.SaveAs(path) ou pdf.BinaryData |
Mapeamentos de propriedades de solicitação de renderização
| Propriedade do modelo jsreport | Equivalente ao IronPDF |
|---|---|
Template.Content |
Primeiro parâmetro para RenderHtmlAsPdf() |
Template.Recipe = Recipe.ChromePdf |
(não é necessário) |
Template.Engine = Engine.None |
(não é necessário) |
Chrome.HeaderTemplate |
RenderingOptions.TextHeader ou HtmlHeader |
Chrome.FooterTemplate |
RenderingOptions.TextFooter ou HtmlFooter |
Chrome.DisplayHeaderFooter |
(automático) |
Chrome.MarginTop |
RenderingOptions.MarginTop |
Mapeamentos de espaços reservados (cabeçalhos/rodapés)
| jsreport - Espaço reservado | Espaço reservado para IronPDF |
|---|---|
<span class='pageNumber'></span> |
{page} |
<span class='totalPages'></span> |
{total-pages} |
{#pageNum} |
{page} |
{#numPages} |
{total-pages} |
{#timestamp} |
{date} |
Exemplos de migração de código
Exemplo 1: HTML básico para PDF
Antes (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
Após (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
A abordagem jsreport requer três pacotes NuGet (jsreport.Binary, jsreport.Local, jsreport.Types), três importações de namespace, execução somente assíncrona, uma cadeia de construtor fluente (LocalReporting().UseBinary().AsUtility().Create()), um RenderRequest verboso com objeto Template aninhado especificando Recipe e Engine, e cópia manual de fluxo para arquivo com um bloco using.
O IronPDF reduz isso a um pacote NuGet , um namespace, três linhas de código e execução síncrona. O método ChromePdfRenderer.RenderHtmlAsPdf() aceita HTML diretamente e retorna um PdfDocument com um método SaveAs() simples. Consulte a documentação de conversão de HTML para PDF para obter opções de renderização adicionais.
Exemplo 2: URL para PDF
Antes (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
Após (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
Este exemplo destaca uma limitação significativa do jsreport: não existe um método direto de URL para PDF. O código jsreport deve usar uma solução alternativa de redirecionamento em JavaScript (window.location='https://example.com') incorporada no conteúdo HTML para capturar uma página da web. Essa abordagem indireta pode falhar em determinados sites e adiciona complexidade desnecessária.
O IronPDF fornece um método dedicado RenderUrlAsPdf() que renderiza diretamente qualquer URL com execução completa de JavaScript e suporte a CSS moderno. Sem soluções alternativas, sem scripts embutidos — basta passar a URL. Saiba mais sobre a conversão de URL para PDF .
Exemplo 3: PDF com cabeçalhos e rodapés
Antes (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
Após (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
A abordagem jsreport requer a adição de um objeto Chrome ao Template, a configuração de DisplayHeaderFooter = true e o uso de modelos HTML com marcadores de posição de classe CSS especiais (<span class='pageNumber'></span>, <span class='totalPages'></span>). Os modelos de cabeçalho e rodapé devem incluir estilos embutidos completos.
IronPDF fornece uma configuração TextHeaderFooter mais limpa com propriedades dedicadas para CenterText, LeftText, RightText e FontSize. Os marcadores de página usam a sintaxe mais simples {page} e {total-pages}. Consulte a documentação sobre cabeçalhos e rodapés para obter opções de cabeçalho HTML.
Notas críticas sobre migração
Elimine o gerenciamento do ciclo de vida do servidor
O jsreport requer gerenciamento explícito do ciclo de vida do servidor:
// 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()
O IronPDF é executado inteiramente no mesmo processo — sem inicialização de servidor, sem gerenciamento de processos, sem limpeza:
// IronPDF:
var renderer = new ChromePdfRenderer();
// Just use it—no lifecycle management needed
// IronPDF:
var renderer = new ChromePdfRenderer();
// Just use it—no lifecycle management needed
Remover pacotes binários específicos da plataforma
O jsreport requer pacotes NuGet separados para cada plataforma de destino:
# 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
O IronPDF lida automaticamente com todos os requisitos da plataforma por meio de um único pacote NuGet .
Atualizar sintaxe do marcador de posição
O jsreport usa marcadores de posição baseados em classes CSS ou chaves. O IronPDF usa uma sintaxe diferente:
// jsreport placeholders:
"<span class='pageNumber'></span>" // or {#pageNum}
"<span class='totalPages'></span>" // or {#numPages}
// IronPDF placeholders:
"{page}"
"{total-pages}"
"{date}"
"{html-title}"
// jsreport placeholders:
"<span class='pageNumber'></span>" // or {#pageNum}
"<span class='totalPages'></span>" // or {#numPages}
// IronPDF placeholders:
"{page}"
"{total-pages}"
"{date}"
"{html-title}"
' jsreport placeholders:
"<span class='pageNumber'></span>" ' or {#pageNum}
"<span class='totalPages'></span>" ' or {#numPages}
' IronPDF placeholders:
"{page}"
"{total-pages}"
"{date}"
"{html-title}"
Substitua Handlebars por interpolação de strings em C
O jsreport frequentemente usa templates Handlebars com Engine.Handlebars:
// jsreport 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 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);
Imports jsreport
Imports IronPdf
' jsreport Handlebars (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)
Simplifique o gerenciamento de fluxos
O jsreport retorna um fluxo que requer cópia manual:
// jsreport 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;
// jsreport 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;
Imports System.IO
' jsreport stream 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
' IronPDF direct access:
pdf.SaveAs("output.pdf")
' Or:
Dim bytes As Byte() = pdf.BinaryData
Solução de problemas
Problema 1: Relatório Local não encontrado
Problema: O código faz referência à classe LocalReporting, que não existe no IronPDF.
Solução: Substitua por 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()
Problema 2: Solicitação de renderização não encontrada
Problema: O código usa objetos wrapper RenderRequest e Template.
Solução: Passe o HTML diretamente para os métodos de renderização:
// 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)
Problema 3: Números de página não aparecem
Problema: Usando a sintaxe de espaço reservado do jsreport <span class='pageNumber'></span>.
Solução: Atualize para a sintaxe de marcador de posição do IronPDF :
// jsreport syntax (won't work)
"Page <span class='pageNumber'></span> of <span class='totalPages'></span>"
// IronPDF syntax
"Page {page} of {total-pages}"
// jsreport syntax (won't work)
"Page <span class='pageNumber'></span> of <span class='totalPages'></span>"
// IronPDF syntax
"Page {page} of {total-pages}"
Problema 4: JsReportBinary não encontrado
Problema: Referências de código JsReportBinary.GetBinary().
Solução: Exclua completamente — o IronPDF não requer binários externos:
// DELETE this jsreport pattern:
.UseBinary(JsReportBinary.GetBinary())
// IronPDF needs nothing—just create the renderer:
var renderer = new ChromePdfRenderer();
// DELETE this jsreport pattern:
.UseBinary(JsReportBinary.GetBinary())
// IronPDF needs nothing—just create the renderer:
var renderer = new ChromePdfRenderer();
Lista de verificação para migração
Pré-migração
- Identificar todas as declarações jsreport
using - Listar modelos usando Handlebars/JsRender (converter para interpolação de strings em C#)
- Documente as opções atuais do Chrome utilizadas (margens, tamanho do papel)
- Verifique se o modo de servidor web está ativado ou se é um modo utilitário (ambos são executados no mesmo processo).
- Observe os pacotes binários específicos da plataforma (exclua todos)
- Obtenha a chave de licença do IronPDF
Alterações no pacote
- Remover o pacote
jsreport.Binary - Remover o pacote
jsreport.Binary.Linux - Remover o pacote
jsreport.Binary.OSX - Remover o pacote
jsreport.Local - Remover o pacote
jsreport.Types - Remover o pacote
jsreport.Client - Instale o pacote
IronPdf
Alterações no código
- Adicionar configuração de chave de licença na inicialização
- Substitua
LocalReportingporChromePdfRenderer - Remover o wrapper
RenderRequest - Remover o wrapper
Template - Atualizar sintaxe do marcador de posição (
<span class='pageNumber'>→{page}) - Substituir Handlebars por interpolação de strings em C#
- Remover chamadas
StartAsync()/KillAsync() - Substitua a cópia de fluxo por
BinaryDataouSaveAs()
Testando
- Testar todos os caminhos de geração de PDF
- Verificar a renderização do cabeçalho/rodapé
- Verifique a numeração das páginas.
- Validar espaçamento das margens
- Teste com páginas CSS/ JavaScript complexas
- Desempenho de referência
Pós-migração
- Excluir arquivos binários do jsreport
- Remova as dependências do Node.js, caso não sejam mais necessárias.
- Atualizar scripts de implantação
- Atualizar documentação

