Como salvar e editar o histórico de revisões de um PDF em C#
A migração doMigraDocpara o IronPDF transforma seu fluxo de trabalho de PDF em .NET , passando de um modelo de documento programático e complexo que exigia a construção manual elemento por elemento para uma abordagem moderna baseada emHTML/CSSque aproveita as habilidades de desenvolvimento web existentes. Este guia fornece um caminho de migração abrangente, passo a passo, que elimina a curva de aprendizado acentuada do modelo de objeto de documento proprietário doMigraDocpara desenvolvedores .NET profissionais.
Por que migrar doMigraDocpara o IronPDF?
Os desafios do MigraDoc
MigraDoc é um mecanismo de layout que se baseia no PDFsharp — ele depende do pacote PDFsharp e renderiza em um PDFsharp PdfDocument. Mantido por empira / a equipe PDFsharp sob a licença MIT, é poderoso para geração programática, mas possui limitações fundamentais que afetam os fluxos de trabalho de desenvolvimento modernos:
-
Sem suporte a HTML: OMigraDocnão oferece suporte direto a HTML. Você deve construir documentos manualmente elemento por elemento usando objetos
Document,Section,Paragraph, eTable— você não pode aproveitar designs existentes em HTML/CSS. -
**Modelo de Documento Proprietário:**MigraDocrequer o aprendizado de um modelo de documento único com conceitos como
AddSection(),AddParagraph(),AddTable(),AddRow(), eAddCell(). Essa curva de aprendizado acentuada é particularmente desafiadora para desenvolvedores com experiência em desenvolvimento web. -
Opções de estilo limitadas: Embora oMigraDocofereça um gerenciamento robusto da estrutura de documentos, seus recursos de estilo são modestos em comparação com as ferramentas da web modernas. Propriedades como
Format.Font.Size,Format.Font.Bold, eFormat.Alignmentsão limitadas em comparação com o CSS3 completo. -
Código Verboso: Criar até mesmo layouts simples requer dezenas de linhas de código. Uma tabela básica com cabeçalhos pode exigir de 15 a 20 linhas de código MigraDoc.
-
Sem suporte aJavaScript: oMigraDocnão consegue renderizar conteúdo dinâmico nem executar JavaScript, o que limita as opções para gráficos modernos e elementos interativos.
-
Gráficos básicos: A funcionalidade de gráficos doMigraDocé limitada em comparação com bibliotecas modernas de gráficos em JavaScript, como Chart.js ou D3.
Comparação entreMigraDoce IronPDF
| Recurso | MigraDoc | IronPDF |
|---|---|---|
| Definição de conteúdo | Programático (Documento/Seção/Parágrafo) | HTML/CSS |
| Curva de Aprendizagem | Íngreme (DOM proprietário) | Fácil (habilidades na web) |
| Estilização | Propriedades limitadas | CSS3 completo |
| JavaScript | None | Execução completa do Chromium |
| Tabelas | Definição manual de coluna/linha | HTML <table> com CSS |
| Gráficos | Gráficos básicos doMigraDoc | Qualquer biblioteca de gráficos emJavaScript |
| Imagens | Dimensionamento/posicionamento manual | HTML padrão <img> |
| Layouts responsivos | Não suportado | Flexbox, Grade |
| Licença | Código aberto (MIT) | Comercial |
Para equipes que visam o .NET moderno,IronPDF permite que os desenvolvedores usem habilidades familiares deHTML/CSSem vez de aprender um modelo de documento proprietário.
Avaliação da Complexidade da Migração
Esforço estimado por funcionalidade
| Recurso | Complexidade da Migração |
|---|---|
| Texto simples | Muito baixo |
| Tabelas | Baixo |
| Cabeçalhos/Rodapés | Baixo |
| Estilos | Médio |
| Imagens | Baixo |
| Gráficos | Médio |
Mudança de paradigma
A mudança fundamental nesta migração doMigraDocé a transição da construção programática de documentos para a renderização com HTML como primeira opção:
MigraDoc: Documento → AdicionarSeção() → AdicionarParágrafo() → RenderizadorDeDocumentoPDF → Salvar()
IronPDF: ChromePdfRenderer → RenderHtmlAsPdf(html) → SaveAs()
Essa mudança de paradigma reduz drasticamente a complexidade do código, ao mesmo tempo que oferece possibilidades ilimitadas de estilização por meio do CSS.
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
# RemoveMigraDocpackages (package IDs are case-sensitive on nuget.org)
dotnet remove package PDFsharp-MigraDoc
dotnet remove package PDFsharp-MigraDoc-GDI
dotnet remove package PDFsharp-MigraDoc-WPF
# 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.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"Identificar o uso do MigraDoc
# Find allMigraDocreferences
grep -r "using MigraDoc\|PdfDocumentRenderer\|AddSection\|AddParagraph" --include="*.cs" .
grep -r "AddTable\|AddRow\|AddColumn\|AddCell\|AddImage" --include="*.cs" .
Referência completa da API
Mapeamentos de Classes
| ClasseMigraDoc | Equivalente ao IronPDF |
|---|---|
Document | ChromePdfRenderer |
Section | HTML <body> ou <div> |
Paragraph | HTML <p>, <h1>, etc. |
FormattedText | HTML <span>, <strong>, etc. |
Table | HTML <table> |
Row | HTML <tr> |
Column | HTML <col> ou CSS |
Cell | HTML <td>, <th> |
PdfDocumentRenderer | ChromePdfRenderer |
Mapeamentos de Métodos
| MétodoMigraDoc | Equivalente ao IronPDF |
|---|---|
document.AddSection() | Estrutura HTML |
section.AddParagraph(text) | <p>text</p> |
section.AddTable() | <table> |
table.AddColumn(width) | Propriedade CSS width |
table.AddRow() | <tr> |
row.Cells[n].AddParagraph() | <td>content</td> |
renderer.RenderDocument() | RenderHtmlAsPdf(html) |
pdfDocument.Save(path) | pdf.SaveAs(path) |
Mapeamentos de espaços reservados (cabeçalhos/rodapés)
| MétodoMigraDoc | Espaço reservado para IronPDF |
|---|---|
AddPageField() | {page} |
AddNumPagesField() | {total-pages} |
AddDateField() | {date} |
Exemplos de migração de código
Exemplo 1: HTML básico para PDF (A diferença fundamental)
Antes (MigraDoc):
// NuGet: Install-Package PDFsharp-MigraDoc-GDI
using MigraDoc.DocumentObjectModel;
using MigraDoc.Rendering;
using System.Diagnostics;
class Program
{
static void Main()
{
//MigraDocdoesn't support HTML directly
// Must manually create document structure
Document document = new Document();
Section section = document.AddSection();
Paragraph paragraph = section.AddParagraph();
paragraph.AddFormattedText("Hello World", TextFormat.Bold);
paragraph.Format.Font.Size = 16;
PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer();
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();
pdfRenderer.PdfDocument.Save("output.pdf");
}
}
Após (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
}
}Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>")
pdf.SaveAs("output.pdf")
End Sub
End ClassEste exemplo ilustra a diferença fundamental entreMigraDoce IronPdf.MigraDocrequer a criação de um Document, a adição de um Section, a adição de um Paragraph, o uso de AddFormattedText() com TextFormat.Bold, configurando Format.Font.Size, criando um PdfDocumentRenderer, atribuindo o documento, chamando RenderDocument(), e finalmente salvando. São mais de 10 linhas de código com múltiplos objetos.
O IronPDF consegue o mesmo resultado em 3 linhas: cria um renderizador, renderiza o HTML e salva. A tag HTML <h1> naturalmente fornece o estilo de cabeçalho em negrito e grande. Consulte a documentação de conversão de HTML para PDF para obter opções de renderização adicionais.
Exemplo 2: Criação de tabelas
Antes (MigraDoc):
// NuGet: Install-Package PDFsharp-MigraDoc-GDI
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
class Program
{
static void Main()
{
Document document = new Document();
Section section = document.AddSection();
Table table = section.AddTable();
table.Borders.Width = 0.75;
Column column1 = table.AddColumn("3cm");
Column column2 = table.AddColumn("3cm");
Row row1 = table.AddRow();
row1.Cells[0].AddParagraph("Name");
row1.Cells[1].AddParagraph("Age");
Row row2 = table.AddRow();
row2.Cells[0].AddParagraph("John");
row2.Cells[1].AddParagraph("30");
PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer();
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();
pdfRenderer.PdfDocument.Save("table.pdf");
}
}
Após (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlTable = @"
<table border='1'>
<tr><th>Name</th><th>Age</th></tr>
<tr><td>John</td><td>30</td></tr>
</table>";
var pdf = renderer.RenderHtmlAsPdf(htmlTable);
pdf.SaveAs("table.pdf");
}
}' NuGet: Install-Package IronPdf
Imports IronPdf
Module Program
Sub Main()
Dim renderer As New ChromePdfRenderer()
Dim htmlTable As String = "
<table border='1'>
<tr><th>Name</th><th>Age</th></tr>
<tr><td>John</td><td>30</td></tr>
</table>"
Dim pdf = renderer.RenderHtmlAsPdf(htmlTable)
pdf.SaveAs("table.pdf")
End Sub
End ModuleA criação de tabelas noMigraDocexige o entendimento da hierarquia Table, Column, Row, e Cell. Você deve adicionar explicitamente colunas com AddColumn(), criar linhas com AddRow(), acessar células por índice com Cells[n], e adicionar conteúdo com AddParagraph(). A borda é definida via table.Borders.Width.
O IronPDF utiliza a sintaxe padrão de tabelas HTML, que qualquer desenvolvedor web conhece. O atributo border='1' fornece a borda, elementos <th> criam células de cabeçalho, e elementos <td> criam células de dados. É possível adicionar CSS para estilização avançada, como listras de zebra, efeitos de foco ou layouts responsivos. Saiba mais sobre como criar tabelas em PDFs .
Exemplo 3: Cabeçalhos e rodapés com números de página
Antes (MigraDoc):
// NuGet: Install-Package PDFsharp-MigraDoc-GDI
using MigraDoc.DocumentObjectModel;
using MigraDoc.Rendering;
class Program
{
static void Main()
{
Document document = new Document();
Section section = document.AddSection();
// Add header
Paragraph headerPara = section.Headers.Primary.AddParagraph();
headerPara.AddText("Document Header");
headerPara.Format.Font.Size = 12;
headerPara.Format.Alignment = ParagraphAlignment.Center;
// Add footer
Paragraph footerPara = section.Footers.Primary.AddParagraph();
footerPara.AddText("Page ");
footerPara.AddPageField();
footerPara.Format.Alignment = ParagraphAlignment.Center;
// Add content
section.AddParagraph("Main content of the document");
PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer();
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();
pdfRenderer.PdfDocument.Save("header-footer.pdf");
}
}
Após (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Document Header"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page}"
};
var pdf = renderer.RenderHtmlAsPdf("<h1>Main content of the document</h1>");
pdf.SaveAs("header-footer.pdf");
}
}Imports IronPdf
Class Program
Shared Sub Main()
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.CenterText = "Document Header"
}
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.CenterText = "Page {page}"
}
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Main content of the document</h1>")
pdf.SaveAs("header-footer.pdf")
End Sub
End ClassCabeçalhos e rodapés noMigraDocexigem acessar section.Headers.Primary e section.Footers.Primary, criando parágrafos dentro deles, adicionando texto com AddText(), e usando métodos especiais como AddPageField() para conteúdo dinâmico. O alinhamento requer a configuração de Format.Alignment.
IronPDF configura cabeçalhos e rodapés em RenderingOptions.TextHeader / RenderingOptions.TextFooter usando TextHeaderFooter, com regiões LeftText, CenterText, e RightText. O espaço reservado {page} insere automaticamente o número da página atual. Para layouts mais ricos, use HtmlHeader / HtmlFooter com HtmlHeaderFooter para suporte completo a HTML/CSS. Consulte a documentação de cabeçalhos e rodapés para opções avançadas.
Notas críticas sobre migração
Sintaxe do marcador de posição do número da página
A mudança mais importante para cabeçalhos e rodapés é a sintaxe dos espaços reservados:
//MigraDocfield methods:
footerPara.AddPageField(); // Current page
footerPara.AddNumPagesField(); // Total pages
//IronPDF placeholders:
"Page {page} of {total-pages}"
Formatar propriedades para CSS
As propriedades Format doMigraDocmapeiam para CSS:
// MigraDoc:
paragraph.Format.Font.Size = 16;
paragraph.Format.Font.Bold = true;
paragraph.Format.Alignment = ParagraphAlignment.Center;
//IronPDF(CSS):
<p style="font-size: 16pt; font-weight: bold; text-align: center;">' MigraDoc:
paragraph.Format.Font.Size = 16
paragraph.Format.Font.Bold = True
paragraph.Format.Alignment = ParagraphAlignment.Center
' IronPDF(CSS):
'<p style="font-size: 16pt; font-weight: bold; text-align: center;">Conversão de unidades
MigraDoc utiliza diversas unidades; As margens do IronPDF são medidas em milímetros:
- "1 cm" = 10 mm
- "1in" = 25,4 mm
- "72pt" = 25,4 mm
// MigraDoc:
table.AddColumn("3cm");
//IronPDF(CSS):
<th style="width: 3cm;">' MigraDoc:
table.AddColumn("3cm")
' IronPDF(CSS):
<th style="width: 3cm;">Alteração do padrão de renderização
Todo o padrão de renderização muda:
//MigraDocpattern (DELETE):
PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer();
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();
pdfRenderer.PdfDocument.Save("output.pdf");
//IronPDF pattern:
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Solução de problemas
Problema 1: Documento/Seção não encontrado
Problema: As classes Document e Section não existem no IronPDF.
Solução: Substitua pela estrutura HTML:
// MigraDoc
Document document = new Document();
Section section = document.AddSection();
// IronPDF
string html = "<html><body>...</body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);Imports MigraDoc.DocumentObjectModel
Imports IronPdf
Dim document As New Document()
Dim section As Section = document.AddSection()
Dim html As String = "<html><body>...</body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)Problema 2: Adicionar parágrafo não encontrado
Problema: O método AddParagraph() não existe.
Solução: Utilize elementos HTML:
// MigraDoc
section.AddParagraph("Hello World");
// IronPDF
"<p>Hello World</p>"netProblema 3: PdfDocumentRenderer não encontrado
Problem: PdfDocumentRenderer class doesn't exist.
Solution: Use ChromePdfRenderer:
// MigraDoc
PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer();
// IronPDF
var renderer = new ChromePdfRenderer();' MigraDoc
Dim pdfRenderer As New PdfDocumentRenderer()
' IronPDF
Dim renderer As New ChromePdfRenderer()Problema 4: AddPageField não funciona
Problema: O método AddPageField() não existe.
Solução: Utilize a sintaxe de marcador de posição do IronPDF:
// MigraDoc
footerPara.AddPageField();
// IronPDF
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page}"
};' MigraDoc
footerPara.AddPageField()
' IronPDF
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.CenterText = "Page {page}"
}Lista de verificação para migração
Pré-migração
- Identifique todas as declarações
usingdo MigraDoc - Estruturas de tabelas de documentos (colunas, linhas, formatação)
- Observe o conteúdo do cabeçalho/rodapé e o uso dos campos da página.
- Liste estilos personalizados definidos com
document.Styles - Obtenha a chave de licença do IronPDF
Alterações no pacote
- Remova os pacotes
PDFsharp-MigraDoc,PDFsharp-MigraDoc-GDI, ePDFsharp-MigraDoc-WPF - Instale o pacote NuGet
IronPdf:dotnet add package IronPdf - Atualizar importações de namespace
Alterações no código
- Adicionar configuração de chave de licença na inicialização
- Substitua
Sectionpor estrutura HTML - Converta
AddParagraph()para elementos HTML<p> - Converta
Cellpara a estrutura HTML<table> - Substitua
AddPageField()por espaço reservado{page} - Substitua
AddNumPagesField()por espaço reservado{total-pages} - Converta propriedades
Formatpara estilos CSS - Substitua
PdfDocumentRendererporChromePdfRenderer
Testando
- Comparar a saída visual entre PDFs antigos e novos
- Verifique se as quebras de página funcionam corretamente.
- Verificar a renderização do cabeçalho/rodapé e a numeração das páginas
- Validar a formatação e as bordas da tabela
- Teste com documentos complexos de várias páginas
Pós-migração
- Remover documentação relacionada ao MigraDoc
- Atualizar os materiais de treinamento da equipe
- Documentar novas localizações de modelos HTML

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais bem estruturados e visualmente atraentes.