ASP.NET CoreでPDFファイルからデータを読み取る方法
手動請求書とラベル生成の問題
2シフトで1日500件の注文を処理する倉庫のフロアでは、ピック・パック・シップのサイクルに摩擦の余地がありません。 OMS画面から1度に1枚の梱包スリップを印刷する、注文詳細をラベルテンプレートに手動でコピーする、または.NETバックエンドとうまく統合できないラベルソフトウェアツールを待つ、これらはすべて注文ごとに数秒ずつ追加され、それが業務終了までに実際のスループット損失に累積します。
エラーのリスクは時間コストとともに累積します。配送先住所が注文記録から直接引き出されるのではなく手作業で転記される際、配送の問題が発生します。 不正な住所による返品配送は、多くの個別注文の利益より多くの労働力と運送料を要します。 運送会社が提供するラベルツールは住所の問題を解決しますが、倉庫フロアが箱の内容を封印前に確認するために必要な項目別の梱包スリップを生成しません。これらは依然として別のシステムからの別個の印刷が必要です。
バッチ印刷はほとんどのアプローチで完全に崩壊します。 業務リーダーが200件の注文ウェーブをリリースする際、梱包スリップはシフト開始時に準備ができていなければならず、注文ごとに新しい印刷ダイアログを開くWebインターフェースを通じて一つずつ生成されることは許容されません。 形式は床のすべてのプリンターで機能しなければならず、それがRazor、インクジェット、またはサーマルであるかを問わず、倉庫のワークステーションに独自のドライバをインストールすることなく使用できるものである必要があります。
シナリオは一貫しています:日々何百もの注文を梱包する直販ブランド、パレット配送のためにマルチラインの請求書を生成するB2Bディストリビューター、組み立てライン作業員のために項目のチェックリストを印刷するサブスクリプションボックスサービス、多様なロゴと返送先住所を持つ複数の商人クライアントの代理でブランド化されたスリップを作成する3PLプロバイダー。
解決策:IronPDFライブラリを使用して注文データから直接生成された印刷用PDFファイル
IronPDFを使用すると、.NET OMSは注文データから印刷用のPDFの梱包スリップやラベルを直接生成できます。 注文が"梱包準備完了"の段階に入ると、アプリケーションは行項目、配送先住所、キャリア情報、および特別指示を取得し、ターゲットの用紙形式に合わせてサイズ変更されたHTMLテンプレートを埋めて、ChromePdfRendererがPDFを生成します。
倉庫スタッフは、標準またはサーマルプリンターのどちらでも出力を印刷できます。注文ごとに1つの文書、または単一印刷ジョブで全体のピックウェーブをカバーするバッチマルチページPDFとして。 独自のラベルソフトウェアはインストール不要、手作業のデータ入力ステップなし、ラベルAPIごとの料金もありません。 レンダリングは既存 for .NETアプリケーション内で外部プロセスなしで単一のNuGetパッケージとして実行されます。
実際の使用方法
1. 注文が梱包キューに入る
注文は、自動的に支払い確認後に"梱包準備完了"に遷移するか、OMSから梱包ウェーブをリリースしたときに倉庫のリーダーによって行われます。 アプリケーションはバッチ内のすべての注文のために、注文データベースをクエリし、SKU、商品名、数量を持つ商品情報を取得します; 発送先住所; キャリアとサービスレベル; 利用可能な場合、事前割り当てられた追跡番号; および特別な取り扱い指示または贈り物メッセージ。
ウェーブ内の各注文には、特定のデータで埋められた同じHTMLテンプレートから生成された独自のPDFがあります。 200件の注文のウェーブでは、200回のレンダリングが行われ、それぞれがミリ秒で完了し、結果は印刷ジョブのために単一の文書にマージされます。
2. テンプレートは両方の形式タイプを処理
梱包スリップテンプレート(レターまたはA4)には、商品ごとの行アイテムテーブルにチェックボックスが含まれ、梱包者が各商品を確認できます。注文番号、発送先住所、およびスキャン可能な注文IDが含まれています。 ラベルテンプレートは4×6インチ(標準のサーマルラベルサイズ)をターゲットとし、発送先住所と返送先住所、キャリアバーコードエリア、および発送重量が含まれています。
両方のテンプレートは、アプリケーションチームが所有するHTMLおよびCSSファイルです。 梱包スリップに新しい列を追加したり、3PL請求書で商人のロゴを変更したり、新しいサーマルプリンターモデルのためにラベルのマージンを調整することはテンプレートファイルの変更です、再コンパイルもビジネスロジックの再配置も必要ありません。
HTMLファイルテンプレートの例

3. バッチレンダリングされて1つの印刷ジョブにマージ
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")
例の出力PDF文書
PdfDocument.Merge()が各個別のスリップを1つの多ページPDFに結合します。 倉庫チームはウェーブ全体を1つの印刷ジョブで、ワークステーションで1クリックで送信し、1つの出力トレイから集めます。
4. ラベル寸法はレンダリングオプションで設定
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")
例の出力PDFファイルと発送ラベル
ゼロマージンによりCSSがラベルエッジまでのすべてのスペーシングをコントロールします。これがサーマルラベルフォーマットにおいてキャリアバーコードエリアは紙の境界から数ミリ以内に到達する必要があるために重要です。
実世界の利点
バッチ効率。 ピックウェーブ全体を1つのPDFにマージすることで、数百の印刷ジョブではなく1つの印刷ジョブで済みます。 シフト開始時間が短縮され、倉庫スタッフは各注文ごとに個別の印刷ダイアログをロードするのを待たなくなります。
印刷互換性。 PDFはRazor、インクジェット、およびサーマルプリンターで一貫してレンダリングされ、倉庫ワークステーションに独自のドライバまたはラベルソフトウェアをインストールする必要がありません。 OMSが生成する形式は、床のすべてのプリンターで受け入れられる形式です。
正確性。 行アイテムと住所は注文記録から直接取得されます。 手動の転記ステップはなく、パッカーに届く前に住所やSKUが誤って入力される経路もありません。
柔軟な形式。 同じ生成パイプラインが、HTMLテンプレートとページサイズオプションを切り替えることによってレターサイズの梱包スリップと4×6ラベルを生成します。 別個のツールや統合も必要ありません。
マルチテナントのブランディング。 3PLプロバイダーはテンプレートパスにmerchantIdを入力し、商人ごとのHTMLファイルを読み込みます。各クライアントのスリップには、それ自体のロゴ、返送先住所、ブランドカラーを持ち込み、追加のロジックなしで同じパイプラインを通過します。
ラベルごとのコストなし。 レンダリングはプロセス内で実行されます。 印刷ごとに呼び出されるサードパーティのラベルAPIはありません、使用メーターはありません、多量のシフトが少量のシフトより高額になる価格モデルもありません。
結び
ピック・パック・シップのサイクルはスループットの問題です。 注文が梱包キューに入り、ラベルが付けられた箱がドックを出るまでの間のすべての手作業ステップは制約です。梱包スリップとラベルの生成は、OMS内部で自動化するのが最も簡単な部分です。
フォーマットごとに1つのHTMLテンプレート、注文ごとに1つのレンダリング呼び出し、ウェーブごとに1つのマージPDF、シフトごとに1つの印刷ジョブ。 IronPDFは、ironpdf.comでC#を使用したPDF生成の完全なライフサイクルを処理し、HTMLテンプレートをレンダリングして文書をマージ、保存、ストリーミングします。 ご自身の注文データと印刷セットアップに向けてパイプラインをテストする準備ができたら、無料の30日間トライアルを始め、今週中に機能するバッチスリップジェネレータを稼働させましょう。




