Ir para o conteúdo do rodapé
USANDO O IRONPDF

Como ler dados de arquivos PDF no ASP.NET Core

O Problema Com a Geração Manual de Etiquetas e Comprovantes

Página inicial do IronPDF Em um chão de armazém processando 500 pedidos por dia em dois turnos, o ciclo de coleta, embalagem e envio não permite atritos. Imprimir comprovantes de embalagem um de cada vez a partir de uma tela OMS, copiando detalhes do pedido em um template de etiqueta à mão, ou esperando uma ferramenta de software de etiquetas que não integra facilmente com o backend .NET, cada uma dessas ações adiciona segundos por pedido que se acumulam em perdas reais de throughput no final do turno.

O risco de erro se acumula juntamente com o custo de tempo. Quando endereços de envio são transcritos manualmente em vez de puxados diretamente do registro do pedido, acidentes de envio acontecem. Uma remessa devolvida devido a um endereço errado custa mais em mão de obra e taxas de transportadora do que a margem na maioria dos pedidos individuais. Ferramentas de etiquetas fornecidas pela transportadora resolvem o problema de endereço, mas não produzem o comprovante de embalagem detalhado que o chão de armazém precisa para verificar o conteúdo da caixa antes de selar; essas ainda exigem uma impressão separada de um sistema diferente.

A impressão em lote é onde a maioria das abordagens falha completamente. Um gerente de operações liberando uma onda de 200 pedidos precisa desses comprovantes de embalagem prontos no início do turno, não gerados um de cada vez através de uma interface web que abre um novo diálogo de impressão por pedido. O formato precisa funcionar em todas as impressoras do chão, seja laser, jato de tinta ou térmica, sem instalar drivers proprietários nas estações de trabalho do armazém.

Os cenários são consistentes: uma marca direta ao consumidor embalando centenas de pedidos por dia, um distribuidor B2B gerando comprovantes de várias linhas para remessas de paletes, um serviço de box de assinatura imprimindo listas de verificação de itens para trabalhadores de linha de montagem, um provedor 3PL produzindo comprovantes de marca em nome de vários clientes de comerciantes com diferentes logotipos e endereços de retorno.

A Solução: Arquivos PDF Prontos Para Impressão Gerados Diretamente a Partir de Dados de Pedido com a Biblioteca IronPDF

IronPDF permite que o .NET OMS gere PDFs prontos para impressão com guias de embalagem e etiquetas diretamente a partir dos dados do pedido. Quando um pedido entra na etapa "pronto para embalar", o aplicativo puxa itens da linha, endereço de envio, informações do transportador e instruções especiais, preenche um modelo HTML dimensionado para o formato de papel-alvo, e ChromePdfRenderer produz o PDF.

A equipe do armazém imprime a saída em qualquer impressora padrão ou térmica, um documento por pedido ou um PDF multi-página em lote cobrindo uma onda de coleta inteira em um único trabalho de impressão. Não há software de etiqueta proprietário para instalar, nenhuma etapa de entrada de dados manual e nenhuma taxa de API por etiqueta. A renderização ocorre dentro do aplicativo .NET existente como um único pacote NuGet sem processos externos.

Como funciona na prática

1. Pedidos Entram na Fila de Embalagem

Um pedido transita para "pronto para embalar" automaticamente após a confirmação do pagamento ou quando um líder de armazém libera uma onda de coleta do OMS. O aplicativo consulta o banco de dados de pedidos para cada pedido no lote, itens de linha com SKU, nome do produto e quantidade; endereço de entrega; transportadora e nível de serviço; número de rastreamento pré-atribuído, se disponível; e quaisquer instruções especiais de manuseio ou mensagens de presente.

Cada pedido na onda recebe seu próprio PDF gerado a partir do mesmo modelo HTML, preenchido com seus dados específicos. Para uma onda de 200 pedidos, são 200 renderizações — cada uma levando milissegundos — antes que os resultados sejam mesclados em um único documento para a tarefa de impressão.

2. Modelos Lidam com Ambos os Tipos de Formato

O modelo de nota de embalagem (carta ou A4) inclui uma tabela de itens de linha com caixas de seleção para o empacotador verificar cada item, o número do pedido, endereço de entrega e um ID de pedido escaneável. O modelo de etiqueta tem como alvo 4×6 polegadas (o tamanho padrão de etiqueta térmica) e inclui os endereços de entrega e devolução, área de código de barras da transportadora e peso do envio.

Ambos os modelos são arquivos HTML e CSS pertencentes à equipe do aplicativo. Atualizar a nota de embalagem para adicionar uma nova coluna, alterar o logotipo de um comerciante em uma nota de 3PL ou ajustar as margens de etiquetas para um novo modelo de impressora térmica é uma alteração de arquivo de modelo, sem recompilação, sem reimplantação da lógica de negócios.

Exemplo de Modelo de Arquivo HTML

Pdf Packing Slips Shipping Labels 2 related to Exemplo de Modelo de Arquivo HTML

3. Lote Renderizado e Mesclado em uma Tarefa de Impressão

using IronPdf;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;

renderer.RenderingOptions.MarginTop = 10;

renderer.RenderingOptions.MarginBottom = 10;

string slipTemplate = await File.ReadAllTextAsync("Templates/packing-slip.html");

var slipPdfs = new List<PdfDocument>();

foreach (var order in pickWave)
{
    string lineItemRows = string.Concat(order.Items.Select(i =>
        $"<tr><td><input type='checkbox'></td><td>{i.Sku}</td><td>{i.ProductName}</td><td>{i.Quantity}</td></tr>"));

    string html = slipTemplate
        .Replace("{{OrderNumber}}", order.OrderNumber)
        .Replace("{{ShipTo}}", order.ShippingAddress.Formatted)
        .Replace("{{LineItems}}", lineItemRows)
        .Replace("{{SpecialInstructions}}", order.SpecialInstructions ?? "None");

    slipPdfs.Add(renderer.RenderHtmlAsPdf(html));
}

PdfDocument waveBatch = PdfDocument.Merge(slipPdfs);

waveBatch.SaveAs($"wave-{pickWave.WaveId}-slips.pdf");
using IronPdf;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;

renderer.RenderingOptions.MarginTop = 10;

renderer.RenderingOptions.MarginBottom = 10;

string slipTemplate = await File.ReadAllTextAsync("Templates/packing-slip.html");

var slipPdfs = new List<PdfDocument>();

foreach (var order in pickWave)
{
    string lineItemRows = string.Concat(order.Items.Select(i =>
        $"<tr><td><input type='checkbox'></td><td>{i.Sku}</td><td>{i.ProductName}</td><td>{i.Quantity}</td></tr>"));

    string html = slipTemplate
        .Replace("{{OrderNumber}}", order.OrderNumber)
        .Replace("{{ShipTo}}", order.ShippingAddress.Formatted)
        .Replace("{{LineItems}}", lineItemRows)
        .Replace("{{SpecialInstructions}}", order.SpecialInstructions ?? "None");

    slipPdfs.Add(renderer.RenderHtmlAsPdf(html));
}

PdfDocument waveBatch = PdfDocument.Merge(slipPdfs);

waveBatch.SaveAs($"wave-{pickWave.WaveId}-slips.pdf");
Imports IronPdf
Imports System.IO

Dim renderer As New ChromePdfRenderer()

renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter

renderer.RenderingOptions.MarginTop = 10

renderer.RenderingOptions.MarginBottom = 10

Dim slipTemplate As String = Await File.ReadAllTextAsync("Templates/packing-slip.html")

Dim slipPdfs As New List(Of PdfDocument)()

For Each order In pickWave
    Dim lineItemRows As String = String.Concat(order.Items.Select(Function(i) $"<tr><td><input type='checkbox'></td><td>{i.Sku}</td><td>{i.ProductName}</td><td>{i.Quantity}</td></tr>"))

    Dim html As String = slipTemplate _
        .Replace("{{OrderNumber}}", order.OrderNumber) _
        .Replace("{{ShipTo}}", order.ShippingAddress.Formatted) _
        .Replace("{{LineItems}}", lineItemRows) _
        .Replace("{{SpecialInstructions}}", If(order.SpecialInstructions, "None"))

    slipPdfs.Add(renderer.RenderHtmlAsPdf(html))
Next

Dim waveBatch As PdfDocument = PdfDocument.Merge(slipPdfs)

waveBatch.SaveAs($"wave-{pickWave.WaveId}-slips.pdf")
$vbLabelText   $csharpLabel

Documento de Saída PDF de Exemplo

Exemplo de saída do IronPDF PdfDocument.Merge() combina cada nota individual em um único PDF de várias páginas. A equipe do armazém envia uma tarefa de impressão para toda a onda, um clique em uma estação de trabalho, uma bandeja de saída para coletar.

4. Dimensões de Etiqueta Definidas através de Opções de Renderização

using IronPdf;

var renderer = new ChromePdfRenderer();

// 4x6 inch thermal label — 288 x 432 points
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Custom;
renderer.RenderingOptions.CustomPaperWidth = 4;
renderer.RenderingOptions.CustomPaperHeight = 6;
renderer.RenderingOptions.MarginTop = 0;
renderer.RenderingOptions.MarginBottom = 0;
renderer.RenderingOptions.MarginLeft = 0;
renderer.RenderingOptions.MarginRight = 0;

string labelHtml = $@"
    <div style='font-family:monospace; padding:4px;'>
        <p><strong>SHIP TO:</strong><br/>{order.ShippingAddress.Formatted}</p>
        <p><strong>FROM:</strong><br/>{order.ReturnAddress.Formatted}</p>
        <p>Order: {order.OrderNumber} | Weight: {order.WeightLbs:F1} lbs</p>
        <p>Carrier: {order.CarrierName} — {order.ServiceLevel}</p>
    </div>";

PdfDocument label = renderer.RenderHtmlAsPdf(labelHtml);

label.SaveAs($"label-{order.OrderNumber}.pdf");
using IronPdf;

var renderer = new ChromePdfRenderer();

// 4x6 inch thermal label — 288 x 432 points
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Custom;
renderer.RenderingOptions.CustomPaperWidth = 4;
renderer.RenderingOptions.CustomPaperHeight = 6;
renderer.RenderingOptions.MarginTop = 0;
renderer.RenderingOptions.MarginBottom = 0;
renderer.RenderingOptions.MarginLeft = 0;
renderer.RenderingOptions.MarginRight = 0;

string labelHtml = $@"
    <div style='font-family:monospace; padding:4px;'>
        <p><strong>SHIP TO:</strong><br/>{order.ShippingAddress.Formatted}</p>
        <p><strong>FROM:</strong><br/>{order.ReturnAddress.Formatted}</p>
        <p>Order: {order.OrderNumber} | Weight: {order.WeightLbs:F1} lbs</p>
        <p>Carrier: {order.CarrierName} — {order.ServiceLevel}</p>
    </div>";

PdfDocument label = renderer.RenderHtmlAsPdf(labelHtml);

label.SaveAs($"label-{order.OrderNumber}.pdf");
Imports IronPdf

Dim renderer As New ChromePdfRenderer()

' 4x6 inch thermal label — 288 x 432 points
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Custom
renderer.RenderingOptions.CustomPaperWidth = 4
renderer.RenderingOptions.CustomPaperHeight = 6
renderer.RenderingOptions.MarginTop = 0
renderer.RenderingOptions.MarginBottom = 0
renderer.RenderingOptions.MarginLeft = 0
renderer.RenderingOptions.MarginRight = 0

Dim labelHtml As String = $"
    <div style='font-family:monospace; padding:4px;'>
        <p><strong>SHIP TO:</strong><br/>{order.ShippingAddress.Formatted}</p>
        <p><strong>FROM:</strong><br/>{order.ReturnAddress.Formatted}</p>
        <p>Order: {order.OrderNumber} | Weight: {order.WeightLbs:F1} lbs</p>
        <p>Carrier: {order.CarrierName} — {order.ServiceLevel}</p>
    </div>"

Dim label As PdfDocument = renderer.RenderHtmlAsPdf(labelHtml)

label.SaveAs($"label-{order.OrderNumber}.pdf")
$vbLabelText   $csharpLabel

Arquivo PDF de Saída e Etiqueta de Envio

Exemplo de nota fiscal gerada e etiqueta de envio Margens zero permitem que o CSS controle todo o espaçamento até a borda da etiqueta, crítico para formatos de etiqueta térmica onde a área de código de barras da transportadora deve alcançar alguns milímetros da borda do papel.

Benefícios no mundo real

Eficiência em lote. Uma onda completa de seleção mesclada em um único PDF significa uma tarefa de impressão em vez de centenas. O tempo de início do turno cai quando a equipe do armazém não está esperando os diálogos de impressão individuais carregarem por pedido.

Compatibilidade de impressão. PDF renderiza consistentemente em impressoras a laser, jato de tinta, e térmicas sem necessidade de instalação de drivers proprietários ou software de etiquetas nas estações de trabalho do armazém. O formato produzido pelo OMS é o formato aceito por todas as impressoras no chão.

Precisão. Itens de linha e endereços são extraídos diretamente do registro do pedido. Não há etapa de transcrição manual e nenhum caminho para um endereço ou SKU serem inseridos incorretamente antes de chegarem ao empacotador.

Formatos flexíveis. O mesmo pipeline de geração produz notas de embalagem no tamanho carta e etiquetas 4×6 ao trocar o modelo HTML e as opções de tamanho da página. Nenhuma ferramenta separada, nenhuma integração separada.

Branding multi-inquilino. Provedores 3PL populam uma variável merchantId no caminho do modelo e carregam um arquivo HTML específico do comerciante, cada nota dos clientes carrega seu próprio logotipo, endereço de retorno e cores da marca através do mesmo pipeline sem lógica adicional.

Sem custos por etiqueta. A renderização é feita no processo. Não há API de etiqueta de terceiros sendo chamada por impressão, sem medição de uso e nenhum modelo de preços que torne uma mudança de alto volume mais cara do que uma de baixo volume.

Encerramento

O ciclo de separação-embalagem-envio é um problema de throughput. Cada etapa manual entre um pedido entrar na fila de embalagem e uma caixa etiquetada sair do cais é uma restrição, e a geração de notas de embalagem e etiquetas é uma que é direta para automatizar dentro do próprio OMS.

Um modelo HTML por formato, uma chamada de renderização por pedido, um PDF mesclado por onda, uma tarefa de impressão por turno. IronPDF lida com o ciclo de vida completo da geração de PDF em C# em ironpdf.com, desde renderizar HTML modelos até mesclar, salvar e transmitir documentos. Se você estiver pronto para testar o pipeline contra seus próprios dados de pedidos e configuração de impressão, comece seu teste gratuito de 30 dias e tenha um gerador de notas em lote funcionando antes do final da semana.

Curtis Chau
Redator Técnico

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

Leia mais

Equipe de Suporte Iron

Estamos online 24 horas por dia, 5 dias por semana.
Bater papo
E-mail
Liga para mim