如何在 C# 中以 PDF/A 合規標準封存 PDF 文件
IronPDF為IronPDF開發人員提供了一條直接建立、轉換和驗證符合ISO 19005標準的歸檔 PDF**的途徑,從而確保文件在任何系統上.NET以相同的方式呈現,無論現在還是幾十年後。 從將HTML 渲染為 PDF/A並將現有文件轉換為PDF/A-1b 、 PDF/A-2b或PDF/A-3b ,到嵌入來源資料以符合ZUGFeRD和Factur-X 電子發票規範, IronPDF可處理完整的PDF/A 轉換**工作流程,而無需離開.NET生態系統。
TL;DR:快速入門指南
本教學涵蓋了在 C# 中建立、轉換和驗證符合 PDF/A 標準的文件——包括電子發票格式和現實世界的政府存檔要求。
-適用對象:使用.NET建立應用程式的開發人員,這些應用程式會產生用於長期儲存或受監管歸檔的文件——政府記錄管理、法律文件、財務審計追蹤、醫療保健記錄保留或電子發票平台,其中 PDF/A 是硬性合規要求。 -你將建立的內容:從零開始建立 HTML 到 PDF/A 的渲染,將現有 PDF 轉換為 PDF/A-1b/2b/3b,為 ZUGFeRD/Factur-X 電子發票嵌入來源資料附件,進行 PDF/A 合規性驗證並報告失敗情況,以及符合 NARA、法院和醫療記錄要求的實際歸檔模式。 -運行環境:任何.NET環境 — .NET 10、 .NET 8 LTS、 .NET Framework 4.6.2+、. .NET Standard 2.0。 PDF/A 轉換和驗證完全在本地運行; 生成過程中不需要外部驗證工具。 -何時使用此方法:當您的應用程式產生必須長期保存的文件時——發票、合約、合規報告、法庭文件或醫療記錄——並且監管要求(NARA、歐盟存檔標準、HIPAA、SEC)要求採用獨立、可驗證的 PDF/A 格式。 -技術上的重要性:標準 PDF 檔案可以引用外部字體、嵌入活動內容,並依賴系統特定的渲染方式——所有這些都會隨著時間的推移而失效。 PDF/A 從格式層面禁止了這些依賴關係,將渲染所需的一切都直接嵌入到文件中,從而保證在任何相容的檢視器上都能獲得完全相同的輸出結果。
只需幾行程式碼即可將現有 PDF 檔案轉換為 PDF/A 格式:
購買或註冊IronPDF的 30 天試用版後,請在應用程式開始時新增您的授權金鑰。
IronPdf.License.LicenseKey = "KEY";
IronPdf.License.LicenseKey = "KEY";
Imports IronPdf
IronPdf.License.LicenseKey = "KEY"
立即開始在您的項目中使用 IronPDF 並免費試用。
目錄
-理解 PDF/A -什麼是 PDF/A?它為什麼重要? PDF/A 版本詳解
- PDF/A-1(基本存檔)
- PDF/A-2(JPEG2000,透明度)
- PDF/A-3(嵌入式文件)
- PDF/A-4(基於 PDF 2.0) -你應該使用哪個版本? 建立 PDF/A 文件 從零開始建立 PDF/A 文檔 -安裝IronPDF -將 HTML 渲染為 PDF/A -將現有 PDF 轉換為 PDF/A -進階 PDF/A 工作流程 -嵌入來源資料(PDF/A-3) -將 XML/CSV 檔案與視覺化文件一起附加
- ZUGFeRD 和 Factur-X 電子發票合規性 -審計追蹤保存 -驗證 PDF/A 合規性 常見合規性問題及解決方法 字體、顏色空間和元資料需求 -真實世界的歸檔場景 -政府檔案管理用例 -美國國家檔案館 (NARA) 要求 -法院文件歸檔 -醫療記錄保存
什麼是PDF/A?它為什麼重要?
PDF/A 是 PDF 格式 (ISO 19005) 的一個 ISO 標準化子集,專門用於電子文件的長期、可靠存檔。 與可以引用外部字體、連結到外部內容並依賴系統特定渲染行為的標準 PDF 不同,PDF/A 文件是完全獨立的。 渲染文件所需的所有字體、顏色設定檔和元資料都直接嵌入到文件中。
這很重要,因為無論作業系統或軟體版本如何,PDF/A 文件無論是在今天打開還是在 100 年後打開,在任何相容的檢視器上,其呈現效果都將完全相同。 它不依賴可能消失的外部資源,不依賴已安裝的特定字體,並且在顏色或透明度的顯示方式上不存在歧義。
除了技術上的可靠性之外,PDF/A 合規性通常是一項硬性要求,而不僅僅是最佳實踐。強制要求 PDF/A 的行業和機構包括:
法律和司法系統—美國、歐盟和許多其他司法管轄區的法院要求或強烈建議使用 PDF/A 格式進行電子歸檔。 美國聯邦法院系統的 CM/ECF 文件歸檔標準將 PDF/A 作為長期記錄保存的首選格式。
政府機構-美國國家檔案館和記錄管理局 (NARA) 指定 PDF/A 為傳輸永久電子記錄的可接受格式。 同樣,歐盟委員會也強制要求某些官方出版物和監管文件採用 PDF/A 格式。
金融服務和審計-美國證券交易委員會等監管機構接受 PDF/A 文件,內部稽核團隊也經常採用 PDF/A 文件,以確保財務報表、報告和支援文件能夠長期保持不可更改和可驗證的狀態。
醫療保健-醫療記錄保存規定(例如美國的 HIPAA)沒有強制規定特定的文件格式,但 PDF/A 已成為存檔患者記錄、影像報告和臨床文件的事實標準,因為它保證了長期可讀性。
簡而言之,當文件必須在時間、系統和組織邊界之間保持不變時,您可以使用 PDF/A 格式。 如果您的應用程式產生的文件可能會在幾年後被引用——發票、合約、合規報告、醫療記錄——PDF/A 是正確的選擇。
PDF/A 版本詳解
PDF/A 標準經歷了多個版本的發展,每個版本都在前一個版本的基礎上進行改進,以支援更多的 PDF 功能,同時保持嚴格的存檔保證。 了解不同版本之間的差異對於選擇適合您使用場景的版本至關重要。
PDF/A-1(基本存檔)
PDF/A-1 (ISO 19005-1:2005) 是該標準的第一個版本,基於 PDF 1.4。它確立了核心存檔要求:所有字體都必須嵌入; 禁止加密; 不允許上傳音訊/視訊內容; 禁止JavaScript 。 PDF/A-1 分為兩個符合性等級:
PDF/A-1b (基本):確保文件的可靠視覺再現。 這是最低合規級別,保證文件渲染後看起來正確。
PDF/A-1a (可存取):在 1b 的基礎上增加了結構和語義要求,包括用於輔助功能的標記內容、Unicode 字元映射和邏輯閱讀順序。 這是更高的標準,也是在無障礙合規性至關重要時所必須達到的標準。
PDF/A-1 是應用最廣泛的版本,至今仍被廣泛使用,尤其是在法律和政府領域,在這些領域,廣泛的兼容性比新功能更為重要。
PDF/A-2(JPEG2000,透明度)
PDF/A-2 (ISO 19005-2:2011) 基於 PDF 1.7,並引入了對 PDF/A-1 中不存在的功能的支援:
JPEG2000 影像壓縮:與 PDF/A-1 中提供的 JPEG 壓縮相比,它提供了更好的品質大小比。
透明度和圖層支援:無需將所有內容扁平化為不透明元素,即可實現更複雜的視覺佈局。
嵌入式 PDF/A 附件: PDF/A-2 文件可以將其他符合 PDF/A 標準的文件作為附件嵌入(但只能是 PDF/A 文件,不能是任意格式)。
PDF/A-2 包含與 PDF/A-1 相同的符合性等級(2b 和 2a),以及一個新的層級: PDF/A-2u ( Unicode ),它要求所有文字都進行 Unicode 映射,但不需要 @@--CODE-655--@@ 層級的完整結構標記。
PDF/A-3(嵌入式文件)
PDF/A-3 (ISO 19005-3:2012) 是現代工作流程中最重要的擴充。 它與 PDF/A-2 (PDF 1.7) 共享相同的基礎,並保留了其所有功能,但增加了一項關鍵功能:能夠在 PDF/A 文件中嵌入任何格式的文件。
這表示您可以將原始 XML 來源資料、CSV 匯出檔案、電子表格或任何其他機器可讀檔案與人可讀的視覺文件一起附加。 PDF/A-3 容器成為一個包含表示層和底層資料的單一軟體包。
這項功能是現代電子發票標準的基礎:
ZUGFeRD:原籍德國,現在已被歐盟採用,稱為Factur-X 。 將結構化的 XML 發票資料(跨行業發票格式)嵌入 PDF/A-3 文件中,該文件同時包含可視化的、易於閱讀的發票。單一文件即可滿足人工和機器處理的需求。
PDF/A-3 符合性等級遵循相同的模式:3a(可存取 + 標記),以及 3u(Unicode 映射)。
PDF/A-4(基於 PDF 2.0)
PDF/A-4 (ISO 19005-4:2020) 是基於 PDF 2.0 的最新版本。它簡化了符合性層級結構; 不再有 a/b/u 的差別。 相反,PDF/A-4 定義了三種規格:
PDF/A-4:通用存檔的基本規格。
PDF/A-4f:允許嵌入任何格式的文件(類似 PDF/A-3)。
PDF/A-4e:專為工程文件設計; 支援 3D 內容、富媒體和其他技術元素。
PDF/A-4 也受益於 PDF 2.0 本身的改進,包括改進的標記結構和使用 XMP(可擴展元資料平台)增強的元資料功能。
PDF/A-4 的採用率正在提高,但與 PDF/A-2 和 PDF/A-3 相比,它仍然沒有得到檢視器和驗證器的普遍支援。
你應該使用哪個版本?
選擇合適的PDF/A版本取決於您的特定需求:

最大相容性:對於現有的系統、驗證器和檢視器(尤其是在法律和政府環境中),請使用PDF/A-1b或PDF/A-2b 。
電子發票:對於需要嵌入式來源資料的 ZUGFeRD、Factur-X 或類似標準,請使用PDF/A-3b 。
無障礙合規性:對於第 508 節或 WCAG 要求,請選擇您正在使用的任何版本的 @@--CODE-662--@@、@@--CODE-663--@@ 或 @@--CODE-664--@@ 的 @@--CODE-661--@@ 符合性等級。
現代工作流程:對於支援 PDF 2.0 的最新功能,請使用PDF/A-4 。
如果拿不定主意, PDF/A-3b能夠在現代性能和廣泛支援之間取得最佳平衡。
從零開始建立 PDF/A 文檔
既然您已經了解了 PDF/A 是什麼以及要針對哪個版本,那麼讓我們開始研究程式碼吧。 IronPDF可以輕鬆地直接從 HTML 內容產生符合 PDF/A 標準的文檔,或將現有的 PDF 轉換為 PDF/A 格式。
安裝IronPDF
開始之前,請將IronPDF NuGet套件安裝到您的.NET專案中。 您可以透過NuGet套件管理器控制台、 .NET CLI 或 Visual Studio NuGet UI 來完成此操作。
Install-Package IronPdf
Install-Package IronPdf
或使用.NET CLI:
dotnet add package IronPdf
dotnet add package IronPdf
IronPDF支援.NET Framework 4.6.2+、. .NET Core、 .NET 5+ 和.NET Standard 2.0,因此幾乎可以融入任何現代.NET項目,無需擔心相容性問題。
將 HTML 渲染為 PDF/A
最常見的工作流程是從 HTML 內容產生 PDF 並直接以 PDF/A 格式儲存。 IronPDF 的 ChromePdfRenderer 方法處理 HTML 到 PDF 的轉換,而 SaveAsPdfA 方法一步處理合規性轉換。
:path=/static-assets/pdf/content-code-examples/tutorials/pdfa-archiving-csharp/pdfa-render-html-to-pdfa.cs
using IronPdf;
// Create HTML content for the document
string htmlContent = @"
E html>
le>
body { font-family: Arial, sans-serif; margin: 40px; }
h1 { color: #2c3e50; }
.section { margin: 20px 0; }
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #ddd; padding: 10px; text-align: left; }
th { background: #3498db; color: white; }
yle>
Quarterly Financial Report</h1>
eport Period: Q4 2025</p>
class='section'>
<table>
<tr><th>Metric</th><th>Value</th></tr>
<tr><td>Total Revenue</td><td>$4.2M</td></tr>
<tr><td>Operating Expenses</td><td>$2.1M</td></tr>
<tr><td>Net Income</td><td>$2.1M</td></tr>
</table>
v>
his document is archived in PDF/A-3b format for long-term preservation.</p>
;
// Render HTML to PDF
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(htmlContent);
// Save as PDF/A-3b for archival compliance
pdf.SaveAsPdfA("quarterly-report-archived.pdf", PdfAVersions.PdfA3b);
Imports IronPdf
' Create HTML content for the document
Dim htmlContent As String = "
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
h1 { color: #2c3e50; }
.section { margin: 20px 0; }
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #ddd; padding: 10px; text-align: left; }
th { background: #3498db; color: white; }
</style>
</head>
<body>
<h1>Quarterly Financial Report</h1>
<p>Report Period: Q4 2025</p>
<div class='section'>
<table>
<tr><th>Metric</th><th>Value</th></tr>
<tr><td>Total Revenue</td><td>$4.2M</td></tr>
<tr><td>Operating Expenses</td><td>$2.1M</td></tr>
<tr><td>Net Income</td><td>$2.1M</td></tr>
</table>
</div>
<p>This document is archived in PDF/A-3b format for long-term preservation.</p>
</body>
</html>
"
' Render HTML to PDF
Dim renderer As New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf(htmlContent)
' Save as PDF/A-3b for archival compliance
pdf.SaveAsPdfA("quarterly-report-archived.pdf", PdfAVersions.PdfA3b)
End Using
輸出
在這個例子中,HTML 使用 IronPDF 基於 Chromium 的渲染引擎渲染成 PDF,從而確保與現代 Web 標準達到像素級的完美保真度。 然後,此方法嵌入所有必要的字體,根據需要轉換色彩空間,去除任何禁止的功能(如JavaScript或外部連結),並寫入符合規範的 XMP 元資料。 最終產生一個完全獨立的 PDF/A-3b 文件,可用於存檔儲存。
這種方法也能與 IronPDF 的其他渲染功能無縫搭配。 您可以新增頁首和頁尾、設定頁面大小和邊距、新增 CSS 樣式,並使用 RenderingOptions 來微調輸出—所有這些操作都可以在 PDF/A 轉換步驟之前完成。 SaveAsPdfA 呼叫會處理合規性轉換,而無需考慮 PDF 的產生方式。
將現有 PDF 轉換為 PDF/A
你不一定總是從HTML開始。 在許多實際場景中,您會收到現有的 PDF 檔案(來自掃描器、第三方系統、舊存檔或使用者上傳),並且需要將它們轉換為 PDF/A 格式以進行合規儲存。
IronPDF使用相同的 SaveAsPdfA 方法處理此問題:
:path=/static-assets/pdf/content-code-examples/tutorials/pdfa-archiving-csharp/pdfa-convert-existing-pdf.cs
using IronPdf;
// Load an existing PDF file
using var pdf = PdfDocument.FromFile("existing-document.pdf");
// Convert and save as PDF/A-3b
// IronPDF automatically embeds fonts, converts color spaces, adds XMP metadata,
// and removes non-compliant features during conversion
pdf.SaveAsPdfA("existing-document-archived.pdf", PdfAVersions.PdfA3b);
// Alternative: Use ConvertToPdfA for in-memory conversion
using var pdf2 = PdfDocument.FromFile("another-document.pdf");
using var pdfA = pdf2.ConvertToPdfA(PdfAVersions.PdfA2b);
pdfA.SaveAs("another-document-archived.pdf");
Imports IronPdf
' Load an existing PDF file
Using pdf As PdfDocument = PdfDocument.FromFile("existing-document.pdf")
' Convert and save as PDF/A-3b
' IronPDF automatically embeds fonts, converts color spaces, adds XMP metadata,
' and removes non-compliant features during conversion
pdf.SaveAsPdfA("existing-document-archived.pdf", PdfAVersions.PdfA3b)
End Using
' Alternative: Use ConvertToPdfA for in-memory conversion
Using pdf2 As PdfDocument = PdfDocument.FromFile("another-document.pdf")
Using pdfA As PdfDocument = pdf2.ConvertToPdfA(PdfAVersions.PdfA2b)
pdfA.SaveAs("another-document-archived.pdf")
End Using
End Using
在轉換過程中, IronPDF會分析現有的 PDF 文件並應用必要的轉換:嵌入任何引用但未包含的字體,將 RGB 或 CMYK 顏色空間轉換為適當的配置文件,添加所需的 XMP 元數據,並刪除任何不合規的功能,例如加密、多媒體或JavaScript。 如果你想在記憶體中進行轉換而不立即儲存到磁碟,也可以使用 ConvertToPdfA 方法——這對於轉換後進行額外處理的管道非常有用。
這種模式非常適合需要將舊文檔儲存庫轉換為符合現代歸檔標準的遷移專案。
嵌入來源資料(PDF/A-3)
PDF/A-3 標準最強大的功能之一是能夠將任意文件(XML、CSV、JSON、電子表格或任何其他格式)直接嵌入到 PDF 文件中。 這使得 PDF 從純粹的視覺文件轉變為混合容器,將人類可讀的呈現方式和機器可讀的來源資料都包含在一個文件中。
將 XML/CSV 檔案與視覺化文件一起附加
核心工作流程很簡單:產生或載入視覺化 PDF,將來源資料檔案作為IronPDF附件附加,然後另存為 PDF/A-3。 IronPDF 支持通過 ConvertToPdfA 方法的多個重載來嵌入文件——您可以直接傳遞文件路徑作為 IEnumerable<string>,使用 EmbedFileByte 處理內存中已有的字節數組,或者使用 EmbedFileStream 處理基於流的工作流程。 每種方法都完全符合 PDF/A 標準。
:path=/static-assets/pdf/content-code-examples/tutorials/pdfa-archiving-csharp/pdfa-embed-xml-attachment.cs
using IronPdf;
using System.Collections.Generic;
// Load the visual PDF document
using var pdf = PdfDocument.FromFile("financial-report.pdf");
// Prepare XML source data to embed
string xmlData = @"<?xml version='1.0' encoding='UTF-8'?>
alReport>
iod>Q4 2025</Period>
enue>4200000</Revenue>
enses>2100000</Expenses>
Income>2100000</NetIncome>
ialReport>";
byte[] xmlBytes = System.Text.Encoding.UTF8.GetBytes(xmlData);
// Configure the embedded file
var xmlConfig = new EmbedFileConfiguration(EmbedFileType.xml)
{
EmbedFileName = "financial-data.xml",
AFDesc = "Source financial data in XML format",
AFRelationship = AFRelationship.Data
};
// Create embed file collection
var embedFiles = new List<EmbedFileByte>
{
new EmbedFileByte(xmlBytes, xmlConfig)
};
// Convert to PDF/A-3b with embedded data
using var archivedPdf = pdf.ConvertToPdfA(embedFiles, PdfAVersions.PdfA3b);
archivedPdf.SaveAs("financial-report-with-data.pdf");
Imports IronPdf
Imports System.Collections.Generic
Imports System.Text
' Load the visual PDF document
Using pdf = PdfDocument.FromFile("financial-report.pdf")
' Prepare XML source data to embed
Dim xmlData As String = "<?xml version='1.0' encoding='UTF-8'?>
<FinancialReport>
<Period>Q4 2025</Period>
<Revenue>4200000</Revenue>
<Expenses>2100000</Expenses>
<NetIncome>2100000</NetIncome>
</FinancialReport>"
Dim xmlBytes As Byte() = Encoding.UTF8.GetBytes(xmlData)
' Configure the embedded file
Dim xmlConfig As New EmbedFileConfiguration(EmbedFileType.xml) With {
.EmbedFileName = "financial-data.xml",
.AFDesc = "Source financial data in XML format",
.AFRelationship = AFRelationship.Data
}
' Create embed file collection
Dim embedFiles As New List(Of EmbedFileByte) From {
New EmbedFileByte(xmlBytes, xmlConfig)
}
' Convert to PDF/A-3b with embedded data
Using archivedPdf = pdf.ConvertToPdfA(embedFiles, PdfAVersions.PdfA3b)
archivedPdf.SaveAs("financial-report-with-data.pdf")
End Using
End Using
這種模式對於財務報告工作流程尤其有價值,其中可視化的 PDF 可能是格式化的資產負債表或損益表,而附加的 XML 或 CSV 文件則包含用於產生報告的原始資料。 審計人員可以檢查可視化文檔,並使用嵌入的來源資料獨立驗證底層數字—所有操作均可從單一文件中完成。您可以透過將其他檔案路徑或位元組陣列傳遞給 ConvertToPdfA 方法的 collection 參數,在相同文件中嵌入多個附件。
ZUGFeRD 和 Factur-X 電子發票合規性
ZUGFeRD(德國電子發票論壇中央使用者指南)及其國際對應標準 Factur-X 是電子發票標準,規定了結構化發票資料應如何嵌入 PDF/A-3 文件中。 可視化的 PDF 文件用作人可讀的發票,而嵌入的 XML 文件(遵循跨行業發票 (CII) 格式)則承載機器可處理的資料。
ZUGFeRD/Factur-X 合規性的關鍵要求如下:
PDF文件必須符合PDF/A-3b(至少)標準。 嵌入的 XML 檔案必須遵循 UN/CEFACT 跨行業發票模式。 XML 檔案必須依照標準規範命名(通常 Factur-X 為 factur-x.xml,ZUGFeRD 為 zugferd-invoice.xml)。 必須設定特定的 XMP 元資料屬性,才能將文件標識為 ZUGFeRD/Factur-X 發票。
IronPDF 的 EmbedFileConfiguration 類別可以讓你對這些要求進行細粒度的控制。 您可以設定 ConformanceLevel(例如 PropertyVersion 和 PropertyVersion 和 AFRelationship 屬性,以匹配目標系統期望的電子發票。
以下是如何使用IronPDF建立符合 ZUGFeRD 標準的發票:
:path=/static-assets/pdf/content-code-examples/tutorials/pdfa-archiving-csharp/pdfa-zugferd-invoice.cs
using IronPdf;
using System.Collections.Generic;
// Create visual invoice HTML
string invoiceHtml = @"
E html>
le>
body { font-family: Arial, sans-serif; margin: 40px; }
.header { border-bottom: 2px solid #e74c3c; padding-bottom: 15px; }
h1 { color: #e74c3c; }
.invoice-details { margin: 30px 0; }
.line-item { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #eee; }
.total { font-size: 20px; font-weight: bold; margin-top: 20px; text-align: right; }
yle>
class='header'>
<h1>INVOICE #INV-2026-0042</h1>
<p>Date: February 7, 2026</p>
v>
class='invoice-details'>
<p><strong>Bill To:</strong> Acme Corporation</p>
<p><strong>Address:</strong> 123 Business Ave, Suite 100</p>
v>
class='line-item'><span>Software License (Enterprise)</span><span>$2,499.00</span></div>
class='line-item'><span>Annual Support Contract</span><span>$499.00</span></div>
class='line-item'><span>Implementation Services</span><span>$1,500.00</span></div>
class='total'>Total: $4,498.00</div>
tyle='margin-top: 40px; font-size: 12px; color: #666;'>
This invoice complies with ZUGFeRD/Factur-X e-invoicing standards.
;
// Render the visual invoice
var renderer = new ChromePdfRenderer();
using var invoicePdf = renderer.RenderHtmlAsPdf(invoiceHtml);
// Prepare ZUGFeRD/Factur-X XML invoice data
string zugferdXml = @"<?xml version='1.0' encoding='UTF-8'?>
ssIndustryInvoice xmlns:rsm='urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100'>
:ExchangedDocument>
<ram:ID>INV-2026-0042</ram:ID>
<ram:IssueDateTime>2026-02-07</ram:IssueDateTime>
m:ExchangedDocument>
:SupplyChainTradeTransaction>
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>USD</ram:InvoiceCurrencyCode>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:GrandTotalAmount>4498.00</ram:GrandTotalAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
m:SupplyChainTradeTransaction>
ossIndustryInvoice>";
byte[] xmlBytes = System.Text.Encoding.UTF8.GetBytes(zugferdXml);
// Configure for ZUGFeRD/Factur-X compliance
var zugferdConfig = new EmbedFileConfiguration(EmbedFileType.xml)
{
EmbedFileName = "factur-x.xml",
AFDesc = "Factur-X Invoice Data",
ConformanceLevel = ConformanceLevel.EN16931,
SchemaNamespace = SchemaNamespace.facturX,
SchemaPrefix = SchemaPrefix.fx,
PropertyVersion = PropertyVersion.v1,
AFRelationship = AFRelationship.Alternative
};
var embedFiles = new List<EmbedFileByte>
{
new EmbedFileByte(xmlBytes, zugferdConfig)
};
// Convert to PDF/A-3b with embedded ZUGFeRD data
using var zugferdInvoice = invoicePdf.ConvertToPdfA(embedFiles, PdfAVersions.PdfA3b);
// Set invoice metadata
zugferdInvoice.MetaData.Title = "Invoice INV-2026-0042";
zugferdInvoice.MetaData.Author = "IronSoftware Billing";
zugferdInvoice.MetaData.Subject = "ZUGFeRD/Factur-X Compliant Invoice";
zugferdInvoice.SaveAs("invoice-zugferd.pdf");
Imports IronPdf
Imports System.Collections.Generic
Imports System.Text
' Create visual invoice HTML
Dim invoiceHtml As String = "
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.header { border-bottom: 2px solid #e74c3c; padding-bottom: 15px; }
h1 { color: #e74c3c; }
.invoice-details { margin: 30px 0; }
.line-item { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #eee; }
.total { font-size: 20px; font-weight: bold; margin-top: 20px; text-align: right; }
</style>
</head>
<body>
<div class='header'>
<h1>INVOICE #INV-2026-0042</h1>
<p>Date: February 7, 2026</p>
</div>
<div class='invoice-details'>
<p><strong>Bill To:</strong> Acme Corporation</p>
<p><strong>Address:</strong> 123 Business Ave, Suite 100</p>
</div>
<div class='line-item'><span>Software License (Enterprise)</span><span>$2,499.00</span></div>
<div class='line-item'><span>Annual Support Contract</span><span>$499.00</span></div>
<div class='line-item'><span>Implementation Services</span><span>$1,500.00</span></div>
<div class='total'>Total: $4,498.00</div>
<p style='margin-top: 40px; font-size: 12px; color: #666;'>
This invoice complies with ZUGFeRD/Factur-X e-invoicing standards.
</p>
</body>
</html>"
' Render the visual invoice
Dim renderer As New ChromePdfRenderer()
Using invoicePdf = renderer.RenderHtmlAsPdf(invoiceHtml)
' Prepare ZUGFeRD/Factur-X XML invoice data
Dim zugferdXml As String = "<?xml version='1.0' encoding='UTF-8'?>
<rsm:CrossIndustryInvoice xmlns:rsm='urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100'>
<rsm:ExchangedDocument>
<ram:ID>INV-2026-0042</ram:ID>
<ram:IssueDateTime>2026-02-07</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>USD</ram:InvoiceCurrencyCode>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:GrandTotalAmount>4498.00</ram:GrandTotalAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>"
Dim xmlBytes As Byte() = Encoding.UTF8.GetBytes(zugferdXml)
' Configure for ZUGFeRD/Factur-X compliance
Dim zugferdConfig As New EmbedFileConfiguration(EmbedFileType.xml) With {
.EmbedFileName = "factur-x.xml",
.AFDesc = "Factur-X Invoice Data",
.ConformanceLevel = ConformanceLevel.EN16931,
.SchemaNamespace = SchemaNamespace.facturX,
.SchemaPrefix = SchemaPrefix.fx,
.PropertyVersion = PropertyVersion.v1,
.AFRelationship = AFRelationship.Alternative
}
Dim embedFiles As New List(Of EmbedFileByte) From {
New EmbedFileByte(xmlBytes, zugferdConfig)
}
' Convert to PDF/A-3b with embedded ZUGFeRD data
Using zugferdInvoice = invoicePdf.ConvertToPdfA(embedFiles, PdfAVersions.PdfA3b)
' Set invoice metadata
zugferdInvoice.MetaData.Title = "Invoice INV-2026-0042"
zugferdInvoice.MetaData.Author = "IronSoftware Billing"
zugferdInvoice.MetaData.Subject = "ZUGFeRD/Factur-X Compliant Invoice"
zugferdInvoice.SaveAs("invoice-zugferd.pdf")
End Using
End Using
輸出
這種方法使您的發票系統能夠在一個符合標準的軟體包中產生既符合人工審核(可視化 PDF)又滿足自動處理(內嵌 XML)要求的文件。
審計追蹤保存
除了電子發票之外,PDF/A-3 的嵌入功能對於任何需要保持完整審計追蹤的工作流程都很有價值。 透過將原始來源資料、處理日誌或變更歷史記錄附加到最終文件中,您可以建立一個獨立的記錄,該記錄可以在將來的任何時間進行獨立驗證。
常見的審計追蹤嵌入模式包括:
財務報表-將原始會計資料(從您的 ERP 系統匯出的 CSV 或 XML 檔案)嵌入到格式化的財務報告旁邊。 審計人員無需存取原始系統即可驗證視覺化文件中的數字與來源資料是否一致。
監管文件-將原始提交資料、驗證結果和任何支持性計算作為嵌入式文件附在最終提交文件中。 這樣就產生了一個包含完整歸檔記錄的單一歸檔包。
合約管理-將版本歷史記錄、核准鍊或已簽署的元資料檔案嵌入到最終執行的合約 PDF 中。 這樣可以將文件的完整生命週期保存在單一歸檔文件中。
:path=/static-assets/pdf/content-code-examples/tutorials/pdfa-archiving-csharp/pdfa-audit-trail.cs
using IronPdf;
using System;
using System.Collections.Generic;
using System.Text.Json;
// Load the final document to archive
using var pdf = PdfDocument.FromFile("executed-contract.pdf");
// Create audit trail data
var auditTrail = new
{
DocumentId = "CONTRACT-2026-00142",
CreatedDate = "2026-01-15T09:30:00Z",
FinalizedDate = "2026-02-07T14:22:00Z",
Versions = new[]
{
new { Version = 1, Date = "2026-01-15", Action = "Draft created", User = "john.smith@company.com" },
new { Version = 2, Date = "2026-01-20", Action = "Legal review completed", User = "legal@company.com" },
new { Version = 3, Date = "2026-02-01", Action = "Client revisions incorporated", User = "john.smith@company.com" },
new { Version = 4, Date = "2026-02-07", Action = "Final execution", User = "ceo@company.com" }
},
Signatures = new[]
{
new { Signer = "Company CEO", SignedDate = "2026-02-07T14:20:00Z", IPAddress = "192.168.1.100" },
new { Signer = "Client Representative", SignedDate = "2026-02-07T14:22:00Z", IPAddress = "10.0.0.50" }
},
Checksum = "SHA256:a1b2c3d4e5f6..."
};
string auditJson = JsonSerializer.Serialize(auditTrail, new JsonSerializerOptions { WriteIndented = true });
byte[] auditBytes = System.Text.Encoding.UTF8.GetBytes(auditJson);
// Configure audit trail attachment
var auditConfig = new EmbedFileConfiguration(EmbedFileType.xml)
{
EmbedFileName = "audit-trail.json",
AFDesc = "Complete document audit trail and version history",
AFRelationship = AFRelationship.Supplement
};
// Create validation log
string validationLog = @"
on Report
=========
: CONTRACT-2026-00142
d: 2026-02-07T14:25:00Z
erformed:
ll required fields present
ignature blocks completed
ate formats valid
urrency amounts verified
egal clauses match template v2.1
atus: APPROVED FOR ARCHIVAL
byte[] validationBytes = System.Text.Encoding.UTF8.GetBytes(validationLog);
var validationConfig = new EmbedFileConfiguration(EmbedFileType.xml)
{
EmbedFileName = "validation-report.txt",
AFDesc = "Pre-archive validation report",
AFRelationship = AFRelationship.Supplement
};
// Embed both files
var embedFiles = new List<EmbedFileByte>
{
new EmbedFileByte(auditBytes, auditConfig),
new EmbedFileByte(validationBytes, validationConfig)
};
// Convert to PDF/A-3b with full audit trail
using var archivedContract = pdf.ConvertToPdfA(embedFiles, PdfAVersions.PdfA3b);
// Set archival metadata
archivedContract.MetaData.Title = "Executed Contract - CONTRACT-2026-00142";
archivedContract.MetaData.Author = "Contract Management System";
archivedContract.MetaData.Subject = "Fully executed agreement with audit trail";
archivedContract.MetaData.Keywords = "contract, executed, 2026, archived";
archivedContract.SaveAs("contract-archived-with-audit.pdf");
Imports IronPdf
Imports System
Imports System.Collections.Generic
Imports System.Text.Json
' Load the final document to archive
Using pdf = PdfDocument.FromFile("executed-contract.pdf")
' Create audit trail data
Dim auditTrail = New With {
.DocumentId = "CONTRACT-2026-00142",
.CreatedDate = "2026-01-15T09:30:00Z",
.FinalizedDate = "2026-02-07T14:22:00Z",
.Versions = New Object() {
New With {.Version = 1, .Date = "2026-01-15", .Action = "Draft created", .User = "john.smith@company.com"},
New With {.Version = 2, .Date = "2026-01-20", .Action = "Legal review completed", .User = "legal@company.com"},
New With {.Version = 3, .Date = "2026-02-01", .Action = "Client revisions incorporated", .User = "john.smith@company.com"},
New With {.Version = 4, .Date = "2026-02-07", .Action = "Final execution", .User = "ceo@company.com"}
},
.Signatures = New Object() {
New With {.Signer = "Company CEO", .SignedDate = "2026-02-07T14:20:00Z", .IPAddress = "192.168.1.100"},
New With {.Signer = "Client Representative", .SignedDate = "2026-02-07T14:22:00Z", .IPAddress = "10.0.0.50"}
},
.Checksum = "SHA256:a1b2c3d4e5f6..."
}
Dim auditJson As String = JsonSerializer.Serialize(auditTrail, New JsonSerializerOptions With {.WriteIndented = True})
Dim auditBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(auditJson)
' Configure audit trail attachment
Dim auditConfig As New EmbedFileConfiguration(EmbedFileType.xml) With {
.EmbedFileName = "audit-trail.json",
.AFDesc = "Complete document audit trail and version history",
.AFRelationship = AFRelationship.Supplement
}
' Create validation log
Dim validationLog As String = "
on Report
=========
: CONTRACT-2026-00142
d: 2026-02-07T14:25:00Z
erformed:
ll required fields present
ignature blocks completed
ate formats valid
urrency amounts verified
egal clauses match template v2.1
atus: APPROVED FOR ARCHIVAL
"
Dim validationBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(validationLog)
Dim validationConfig As New EmbedFileConfiguration(EmbedFileType.xml) With {
.EmbedFileName = "validation-report.txt",
.AFDesc = "Pre-archive validation report",
.AFRelationship = AFRelationship.Supplement
}
' Embed both files
Dim embedFiles As New List(Of EmbedFileByte) From {
New EmbedFileByte(auditBytes, auditConfig),
New EmbedFileByte(validationBytes, validationConfig)
}
' Convert to PDF/A-3b with full audit trail
Using archivedContract = pdf.ConvertToPdfA(embedFiles, PdfAVersions.PdfA3b)
' Set archival metadata
archivedContract.MetaData.Title = "Executed Contract - CONTRACT-2026-00142"
archivedContract.MetaData.Author = "Contract Management System"
archivedContract.MetaData.Subject = "Fully executed agreement with audit trail"
archivedContract.MetaData.Keywords = "contract, executed, 2026, archived"
archivedContract.SaveAs("contract-archived-with-audit.pdf")
End Using
End Using
驗證 PDF/A 合規性
建立文件並將其命名為 PDF/A 是不夠的——您還需要驗證輸出是否真正符合標準的要求。 聲稱是 PDF/A 格式但未通過驗證的文件將不會被存檔系統、政府入口網站或電子發票平台接受。
IronPDF 的 SaveAsPdfA 和 ConvertToPdfA 方法可以處理合規性轉換的繁重工作——嵌入字體、轉換顏色空間、移除禁止的功能以及寫入 XMP 元資料。 但是,為了獨立驗證輸出結果,您應該使用專用的外部工具進行驗證,例如veraPDF (業界標準的開源 PDF/A 驗證器)或 Adobe Acrobat Pro 的內建預檢工具。 將 veraPDF 整合到您的 CI/CD 管道或文件處理工作流程中,可讓您獲得權威的第三方確認,確保產生的每個文件在儲存或分發之前都符合所宣稱的標準。
常見合規性問題及解決方法
即使IronPDF處理了大部分合規性工作,某些輸入條件仍可能導致驗證失敗。 以下是一些最常見的問題以及解決方法:
未嵌入字體-這是最常見的故障。 如果來源 PDF 透過名稱引用字體,但沒有嵌入字體數據,則輸出將不符合 PDF/A 標準。 IronPDF會在轉換過程中嘗試自動嵌入字體,但如果IronPDF運行的系統上沒有字體文件,則嵌入會失敗。 解決方法:確保原始文件中使用的所有字型都已安裝在伺服器上,或在 HTML 內容中使用通用的 Web 安全字型。
不支援的色彩空間— PDF/A 要求所有色彩資料都必須在特定的嵌入式色彩設定檔中定義(通常螢幕文件使用 sRGB 設定文件,列印文件使用 CMYK 設定檔)。 使用裝置相關色彩空間且沒有嵌入式設定檔的來源 PDF 檔案將無法通過驗證。 修正: IronPDF在大多數情況下會自動處理色彩空間轉換。 對於特殊情況,請確保您的來源內容以 sRGB 格式指定顏色。
加密或密碼保護-PDF/A 嚴格禁止加密。 如果要轉換受密碼保護的 PDF 文件,必須先解密。解決方法:使用 PdfDocument.FromFile("encrypted.pdf", "password") 開啟受保護的檔案後再進行轉換。
JavaScript或多媒體內容— PDF/A 禁止使用JavaScript、音訊、視訊和其他互動元素。 如果您的來源 HTML 包含 <script> 標籤、嵌入式影片或互動式表單,則需要將其刪除,否則轉換過程會將其移除。 解決方法:在渲染為 PDF/A 之前,請確保 HTML 內容是靜態的。
透明度問題(僅限 PDF/A-1) — PDF/A-1 不支援透明度。 如果您的文件包含透明元素(在現代 CSS 佈局中很常見),則轉換為 PDF/A-1 需要進行扁平化處理。 修正:如果您的文件使用透明度,請以 PDF/A-2 或更高版本為目標;或者,在以 PDF/A-1 為目標時,請確保 CSS 不使用 rgba 或透明 PNG。
字體、顏色空間和元資料需求
了解 PDF/A 合規性的三大支柱——字體、色彩空間和元資料——有助於您設計出能夠一次性通過驗證的文件。
Fonts:文件中使用的每種字體都必須完全嵌入。 這包括文本中出現的所有字形,而不僅僅是其中的一部分。 對於 PDF/A-1a、2a 和 3a 符合性級別,每個字元都必須有 Unicode 映射,以確保可以可靠地提取和搜尋文字。
使用 IronPDF 的 HTML 轉 PDF 渲染功能時,Chromium 引擎會自動嵌入系統中可用的字型。 為了確保不同部署環境(開發、測試、生產)之間的一致性,請考慮在 HTML 中使用透過 <link> 標籤載入的 Google Fonts,或將字型檔案打包到您的應用程式中,並透過 CSS @font-face 引用它們。
色彩空間: PDF/A 要求所有顏色都必須在與裝置無關的色彩空間內指定,該色彩空間需由 ICC 設定檔支援。實際上,這意味著大多數文件都應使用 sRGB 色彩空間。 IronPDF會在轉換過程中嵌入相應的 ICC 配置文件並自動轉換顏色——如果您的工作流程需要特定的配置文件,您也可以傳遞自訂的 ICC 文件路徑。但是,如果您處理的是需要 CMYK 精確度的印刷文檔,請確保來源內容使用 CMYK 相容的配置文件,並在轉換過程中保留這些配置文件。
Metadata: PDF/A 要求將 XMP(可擴充元資料平台)元資料嵌入到文件中。 這包括文件標題、作者、建立日期、修改日期和 PDF/A 合規層級識別碼。 IronPDF會自動填入這些字段,但您也可以透過 MetaData 屬性明確設定它們,以便更好地控制:
:path=/static-assets/pdf/content-code-examples/tutorials/pdfa-archiving-csharp/pdfa-metadata-settings.cs
using IronPdf;
using System;
// Create a PDF document
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf("<h1>Annual Report 2025</h1><p>Corporate performance summary.</p>");
// Set standard metadata properties
pdf.MetaData.Title = "Annual Report 2025 - IronSoftware Inc.";
pdf.MetaData.Author = "Finance Department";
pdf.MetaData.Subject = "Corporate annual financial and operational report";
pdf.MetaData.Keywords = "annual report, financial, 2025, corporate, IronSoftware";
pdf.MetaData.Creator = "IronPDF Document Generator";
pdf.MetaData.CreationDate = DateTime.Now;
pdf.MetaData.ModifiedDate = DateTime.Now;
// For custom or batch metadata, use SetMetaDataDictionary
var metadataDict = new System.Collections.Generic.Dictionary<string, string>
{
{ "Title", "Quarterly Report Q4 2025" },
{ "Author", "Finance Team" },
{ "Subject", "Q4 Financial Results" },
{ "Keywords", "quarterly, Q4, 2025, finance" },
{ "Department", "Finance" },
{ "Classification", "Internal" },
{ "RetentionPeriod", "7 years" }
};
using var pdf2 = renderer.RenderHtmlAsPdf("<h1>Q4 Report</h1>");
pdf2.MetaData.SetMetaDataDictionary(metadataDict);
// Convert to PDF/A with metadata preserved
pdf.SaveAsPdfA("annual-report-2025.pdf", PdfAVersions.PdfA3b);
pdf2.SaveAsPdfA("q4-report-2025.pdf", PdfAVersions.PdfA3b);
Imports IronPdf
Imports System
Imports System.Collections.Generic
' Create a PDF document
Dim renderer As New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf("<h1>Annual Report 2025</h1><p>Corporate performance summary.</p>")
' Set standard metadata properties
pdf.MetaData.Title = "Annual Report 2025 - IronSoftware Inc."
pdf.MetaData.Author = "Finance Department"
pdf.MetaData.Subject = "Corporate annual financial and operational report"
pdf.MetaData.Keywords = "annual report, financial, 2025, corporate, IronSoftware"
pdf.MetaData.Creator = "IronPDF Document Generator"
pdf.MetaData.CreationDate = DateTime.Now
pdf.MetaData.ModifiedDate = DateTime.Now
' For custom or batch metadata, use SetMetaDataDictionary
Dim metadataDict As New Dictionary(Of String, String) From {
{"Title", "Quarterly Report Q4 2025"},
{"Author", "Finance Team"},
{"Subject", "Q4 Financial Results"},
{"Keywords", "quarterly, Q4, 2025, finance"},
{"Department", "Finance"},
{"Classification", "Internal"},
{"RetentionPeriod", "7 years"}
}
Using pdf2 = renderer.RenderHtmlAsPdf("<h1>Q4 Report</h1>")
pdf2.MetaData.SetMetaDataDictionary(metadataDict)
' Convert to PDF/A with metadata preserved
pdf.SaveAsPdfA("annual-report-2025.pdf", PdfAVersions.PdfA3b)
pdf2.SaveAsPdfA("q4-report-2025.pdf", PdfAVersions.PdfA3b)
End Using
End Using
對於將被記錄管理系統索引的文件而言,明確設定元資料尤其重要,因為標題和作者欄位經常用於編目和搜尋。
政府檔案管理用例
PDF/A 不僅僅是一項技術規範,它在許多政府、法律和醫療保健領域都是一項實際要求。 在本節中,我們將探討 PDF/A 如何融入特定的監管框架,以及使用IronPDF滿足其要求需要了解哪些內容。
美國國家檔案館 (NARA) 要求
美國國家檔案館和記錄管理局(NARA)負責保存具有永久價值的聯邦記錄。 美國國家檔案館的傳輸指南明確指出,PDF/A 是向國家檔案館傳輸永久電子記錄的首選格式之一。
美國國家檔案館 (NARA) 對 PDF/A 格式文件提交的主要要求:
美國國家檔案館 (NARA) 接受大多數記錄類型的PDF/A-1、PDF/A-2 和 PDF/A-3 格式檔案。文件在傳輸前必須與所聲稱的 PDF/A 版本進行驗證。 元資料必須包括建立機構、記錄系列識別碼和涵蓋的日期範圍。 必須使用嵌入式字體-美國國家檔案館明確拒絕缺少字體或僅引用字體的文件。 對於數位化(掃描)記錄,NARA 建議最低解析度為300 DPI ,並建議PDF/A-2或更高版本,因為這些格式的影像壓縮效果較好。
以下是如何準備一批機構檔案以供移交至美國國家檔案館 (NARA) 的方法:
輸入

:path=/static-assets/pdf/content-code-examples/tutorials/pdfa-archiving-csharp/pdfa-nara-compliance.cs
using IronPdf;
using System;
using System.IO;
string inputFolder = "agency-records/";
string validatedFolder = "nara-transfer/validated/";
string rejectedFolder = "nara-transfer/rejected/";
// Create output directories
Directory.CreateDirectory(validatedFolder);
Directory.CreateDirectory(rejectedFolder);
// NARA transfer metadata requirements
string agencyName = "Department of Example";
string recordSeries = "Administrative Correspondence";
string dateRange = "2020-2025";
// Process all PDF files in the input folder
string[] pdfFiles = Directory.GetFiles(inputFolder, "*.pdf");
Console.WriteLine($"Preparing {pdfFiles.Length} records for NARA transfer");
Console.WriteLine($"Agency: {agencyName}");
Console.WriteLine($"Record Series: {recordSeries}");
Console.WriteLine();
int successCount = 0;
int failCount = 0;
foreach (string inputPath in pdfFiles)
{
string fileName = Path.GetFileName(inputPath);
try
{
using var pdf = PdfDocument.FromFile(inputPath);
// Set NARA-required metadata
var metadata = new System.Collections.Generic.Dictionary<string, string>
{
{ "Title", Path.GetFileNameWithoutExtension(inputPath) },
{ "Author", agencyName },
{ "Subject", recordSeries },
{ "Keywords", $"NARA, {recordSeries}, {dateRange}" },
{ "Agency", agencyName },
{ "RecordSeries", recordSeries },
{ "DateRange", dateRange },
{ "TransferDate", DateTime.Now.ToString("yyyy-MM-dd") }
};
pdf.MetaData.SetMetaDataDictionary(metadata);
// Convert to PDF/A-2b (NARA preferred for digitized records)
string outputPath = Path.Combine(validatedFolder, fileName);
pdf.SaveAsPdfA(outputPath, PdfAVersions.PdfA2b);
// Verify the output
using var verifyPdf = PdfDocument.FromFile(outputPath);
if (verifyPdf.PageCount > 0)
{
successCount++;
Console.WriteLine($"[OK] {fileName}");
}
else
{
throw new Exception("Output PDF has no pages");
}
}
catch (Exception ex)
{
failCount++;
Console.WriteLine($"[FAILED] {fileName}: {ex.Message}");
// Move original to rejected folder for manual review
try
{
File.Copy(inputPath, Path.Combine(rejectedFolder, fileName), overwrite: true);
}
catch { }
}
}
Console.WriteLine();
Console.WriteLine("=== NARA Transfer Preparation Complete ===");
Console.WriteLine($"Successfully converted: {successCount}");
Console.WriteLine($"Failed (requires review): {failCount}");
Console.WriteLine($"Output location: {validatedFolder}");
Imports IronPdf
Imports System
Imports System.IO
Module Program
Sub Main()
Dim inputFolder As String = "agency-records/"
Dim validatedFolder As String = "nara-transfer/validated/"
Dim rejectedFolder As String = "nara-transfer/rejected/"
' Create output directories
Directory.CreateDirectory(validatedFolder)
Directory.CreateDirectory(rejectedFolder)
' NARA transfer metadata requirements
Dim agencyName As String = "Department of Example"
Dim recordSeries As String = "Administrative Correspondence"
Dim dateRange As String = "2020-2025"
' Process all PDF files in the input folder
Dim pdfFiles As String() = Directory.GetFiles(inputFolder, "*.pdf")
Console.WriteLine($"Preparing {pdfFiles.Length} records for NARA transfer")
Console.WriteLine($"Agency: {agencyName}")
Console.WriteLine($"Record Series: {recordSeries}")
Console.WriteLine()
Dim successCount As Integer = 0
Dim failCount As Integer = 0
For Each inputPath As String In pdfFiles
Dim fileName As String = Path.GetFileName(inputPath)
Try
Using pdf = PdfDocument.FromFile(inputPath)
' Set NARA-required metadata
Dim metadata As New System.Collections.Generic.Dictionary(Of String, String) From {
{"Title", Path.GetFileNameWithoutExtension(inputPath)},
{"Author", agencyName},
{"Subject", recordSeries},
{"Keywords", $"NARA, {recordSeries}, {dateRange}"},
{"Agency", agencyName},
{"RecordSeries", recordSeries},
{"DateRange", dateRange},
{"TransferDate", DateTime.Now.ToString("yyyy-MM-dd")}
}
pdf.MetaData.SetMetaDataDictionary(metadata)
' Convert to PDF/A-2b (NARA preferred for digitized records)
Dim outputPath As String = Path.Combine(validatedFolder, fileName)
pdf.SaveAsPdfA(outputPath, PdfAVersions.PdfA2b)
' Verify the output
Using verifyPdf = PdfDocument.FromFile(outputPath)
If verifyPdf.PageCount > 0 Then
successCount += 1
Console.WriteLine($"[OK] {fileName}")
Else
Throw New Exception("Output PDF has no pages")
End If
End Using
End Using
Catch ex As Exception
failCount += 1
Console.WriteLine($"[FAILED] {fileName}: {ex.Message}")
' Move original to rejected folder for manual review
Try
File.Copy(inputPath, Path.Combine(rejectedFolder, fileName), overwrite:=True)
Catch
End Try
End Try
Next
Console.WriteLine()
Console.WriteLine("=== NARA Transfer Preparation Complete ===")
Console.WriteLine($"Successfully converted: {successCount}")
Console.WriteLine($"Failed (requires review): {failCount}")
Console.WriteLine($"Output location: {validatedFolder}")
End Sub
End Module
輸出

在準備向美國國家檔案館移交檔案時,逐一驗證每個文件至關重要。 美國國家檔案館的接收流程會拒絕不合規的文件,重新處理大量文件既費時又費力。 將驗證直接建置到轉換管道中—在每次呼叫 SaveAsPdfA 後使用 veraPDF 等工具—是最可靠的方法。
法院文件歸檔
美國聯邦法院系統和許多州法院系統使用電子歸檔系統(聯邦層級主要是 CM/ECF),這些系統接受或要求 PDF/A 格式以進行長期記錄保存。 雖然具體要求因地區而異,但整體預期是一致的:
聯邦法院—美國法院行政辦公室建議將成為永久案件記錄一部分的文件採用 PDF/A 格式。 CM/ECF 系統通常接受 PDF/A-1b 作為最低標準,但對於格式複雜的文檔,PDF/A-2b 越來越受歡迎。
各州法院的要求差異很大。 有些州(例如德克薩斯州和加利福尼亞州)對特定類型的文件有明確的PDF/A格式要求,而其他州則只是將其作為最佳實踐建議。務必查閱目標司法管轄區的具體規定。
各法院系統普遍要求包括:
文件必須能夠進行文字搜尋(而不僅僅是掃描影像),這意味著盡可能使用 PDF/A-1a 或 2a 合規性,或確保已對掃描文件套用 OCR。 頁面尺寸必須為標準尺寸(通常為美式信紙,8.5" × 11")。 元資料應包括案件編號、提交日期和文件類型(如果歸檔系統支援)。
:path=/static-assets/pdf/content-code-examples/tutorials/pdfa-archiving-csharp/pdfa-court-filing.cs
using IronPdf;
using System;
// Court filing configuration
string caseNumber = "1:26-cv-00142-ABC";
string courtName = "US District Court, Northern District";
string documentType = "Motion for Summary Judgment";
string filingParty = "Plaintiff";
// Create legal document HTML
string legalDocumentHtml = $@"
E html>
le>
body {{
font-family: 'Times New Roman', Times, serif;
font-size: 12pt;
line-height: 2;
margin: 1in;
}}
.header {{ text-align: center; margin-bottom: 24pt; }}
.case-caption {{
border: 1px solid black;
padding: 12pt;
margin: 24pt 0;
}}
.section {{ margin: 12pt 0; }}
h1 {{ font-size: 14pt; text-align: center; }}
.signature {{ margin-top: 48pt; }}
yle>
class='header'>
<strong>{courtName}</strong>
v>
class='case-caption'>
<p>ACME CORPORATION,<br> Plaintiff,</p>
<p>v.</p>
<p>EXAMPLE INDUSTRIES, INC.,<br> Defendant.</p>
<p style='text-align: right;'><strong>Case No. {caseNumber}</strong></p>
v>
{documentType.ToUpper()}</h1>
class='section'>
<p>Plaintiff ACME Corporation, by and through undersigned counsel, respectfully
moves this Court for summary judgment pursuant to Federal Rule of Civil Procedure 56...</p>
v>
class='section'>
<h2>I. INTRODUCTION</h2>
<p>This motion presents the Court with a straightforward question of contract interpretation...</p>
v>
class='signature'>
<p>Respectfully submitted,</p>
<p>_________________________<br>
Jane Attorney, Esq.<br>
Bar No. 12345<br>
Law Firm LLP<br>
123 Legal Street<br>
City, State 12345<br>
(555) 123-4567<br>
jane@lawfirm.com</p>
<p>Attorney for Plaintiff</p>
v>
;
// Render with court-appropriate settings
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;
renderer.RenderingOptions.MarginTop = 72;
renderer.RenderingOptions.MarginBottom = 72;
renderer.RenderingOptions.MarginLeft = 72;
renderer.RenderingOptions.MarginRight = 72;
using var pdf = renderer.RenderHtmlAsPdf(legalDocumentHtml);
// Set metadata for court filing system indexing
var metadata = new System.Collections.Generic.Dictionary<string, string>
{
{ "Title", $"{documentType} - {caseNumber}" },
{ "Author", "Law Firm LLP" },
{ "Subject", $"Court Filing - {caseNumber}" },
{ "CaseNumber", caseNumber },
{ "DocumentType", documentType },
{ "FilingParty", filingParty },
{ "FilingDate", DateTime.Now.ToString("yyyy-MM-dd") }
};
pdf.MetaData.SetMetaDataDictionary(metadata);
// Convert to PDF/A-2b (widely accepted by federal courts)
string outputPath = $"court-filing-{caseNumber.Replace(":", "-")}.pdf";
pdf.SaveAsPdfA(outputPath, PdfAVersions.PdfA2b);
Imports IronPdf
Imports System
Imports System.Collections.Generic
' Court filing configuration
Dim caseNumber As String = "1:26-cv-00142-ABC"
Dim courtName As String = "US District Court, Northern District"
Dim documentType As String = "Motion for Summary Judgment"
Dim filingParty As String = "Plaintiff"
' Create legal document HTML
Dim legalDocumentHtml As String = $"
<!DOCTYPE html>
<html>
<head>
<style>
body {{
font-family: 'Times New Roman', Times, serif;
font-size: 12pt;
line-height: 2;
margin: 1in;
}}
.header {{ text-align: center; margin-bottom: 24pt; }}
.case-caption {{
border: 1px solid black;
padding: 12pt;
margin: 24pt 0;
}}
.section {{ margin: 12pt 0; }}
h1 {{ font-size: 14pt; text-align: center; }}
.signature {{ margin-top: 48pt; }}
</style>
</head>
<body>
<div class='header'>
<strong>{courtName}</strong>
</div>
<div class='case-caption'>
<p>ACME CORPORATION,<br> Plaintiff,</p>
<p>v.</p>
<p>EXAMPLE INDUSTRIES, INC.,<br> Defendant.</p>
<p style='text-align: right;'><strong>Case No. {caseNumber}</strong></p>
</div>
<h1>{documentType.ToUpper()}</h1>
<div class='section'>
<p>Plaintiff ACME Corporation, by and through undersigned counsel, respectfully
moves this Court for summary judgment pursuant to Federal Rule of Civil Procedure 56...</p>
</div>
<div class='section'>
<h2>I. INTRODUCTION</h2>
<p>This motion presents the Court with a straightforward question of contract interpretation...</p>
</div>
<div class='signature'>
<p>Respectfully submitted,</p>
<p>_________________________<br>
Jane Attorney, Esq.<br>
Bar No. 12345<br>
Law Firm LLP<br>
123 Legal Street<br>
City, State 12345<br>
(555) 123-4567<br>
jane@lawfirm.com</p>
<p>Attorney for Plaintiff</p>
</div>
</body>
</html>
"
' Render with court-appropriate settings
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter
renderer.RenderingOptions.MarginTop = 72
renderer.RenderingOptions.MarginBottom = 72
renderer.RenderingOptions.MarginLeft = 72
renderer.RenderingOptions.MarginRight = 72
Using pdf = renderer.RenderHtmlAsPdf(legalDocumentHtml)
' Set metadata for court filing system indexing
Dim metadata As New Dictionary(Of String, String) From {
{"Title", $"{documentType} - {caseNumber}"},
{"Author", "Law Firm LLP"},
{"Subject", $"Court Filing - {caseNumber}"},
{"CaseNumber", caseNumber},
{"DocumentType", documentType},
{"FilingParty", filingParty},
{"FilingDate", DateTime.Now.ToString("yyyy-MM-dd")}
}
pdf.MetaData.SetMetaDataDictionary(metadata)
' Convert to PDF/A-2b (widely accepted by federal courts)
Dim outputPath As String = $"court-filing-{caseNumber.Replace(":", "-")}.pdf"
pdf.SaveAsPdfA(outputPath, PdfAVersions.PdfA2b)
End Using
輸出
對於建置文件管理系統的律師事務所和法律科技公司而言,將 PDF/A 轉換整合到歸檔工作流程中,可確保每個歸檔的文件都符合法院的長期保存要求,而無需律師助理或律師的手動介入。
醫療記錄保存
醫療機構在保存病患記錄方面面臨嚴格的要求。 雖然 HIPAA 沒有強制規定特定的文件格式,但考慮到較長的保質期(成人通常為 7-10 年,未成年人更長)、可訪問性要求和審計預期,PDF/A 自然成為醫療文件存檔的選擇。
醫療記錄歸檔的關鍵考慮因素:
保質期-聯邦和州法規要求醫療記錄保質期各不相同,通常長達 10 年以上。 PDF/A 格式保證了長期可讀性,因此非常適合滿足這些要求,而無需擔心格式過時。
無障礙性-《美國殘障法案》和《康復法案》第 508 條要求電子病歷必須具有無障礙性。 使用 PDF/A-2a 或 PDF/A-3a 符合性等級(包括結構標記)有助於滿足這些無障礙要求。
互通性-醫療記錄經常在醫療服務提供者、保險公司和病患之間共用。 PDF/A 的自包含特性可確保無論使用何種檢視器或系統開啟文檔,文件都能一致地呈現。
審計準備-醫療保健審計可能需要提供多年前創建的醫療記錄。 PDF/A 確保審計過程中產生的文件與原件完全一致,不存在任何可能引起對文件完整性質疑的渲染差異。
:path=/static-assets/pdf/content-code-examples/tutorials/pdfa-archiving-csharp/pdfa-medical-records.cs
using IronPdf;
using System;
using System.Collections.Generic;
// Medical record metadata
string patientId = "MRN-2026-00847";
string documentType = "Discharge Summary";
string facility = "Metro General Hospital";
string department = "Internal Medicine";
DateTime encounterDate = new DateTime(2026, 2, 5);
// Create clinical document HTML
string clinicalDocumentHtml = $@"
E html>
ng='en'>
le>
body {{ font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }}
.header {{ border-bottom: 2px solid #2c3e50; padding-bottom: 15px; margin-bottom: 20px; }}
.patient-info {{ background: #ecf0f1; padding: 15px; margin: 15px 0; }}
.section {{ margin: 20px 0; }}
h1 {{ color: #2c3e50; }}
h2 {{ color: #3498db; font-size: 14pt; }}
.footer {{ margin-top: 40px; font-size: 10pt; color: #666; }}
yle>
class='header'>
<h1>{facility}</h1>
<p>{department} | {documentType}</p>
v>
class='patient-info'>
<p><strong>Patient ID:</strong> {patientId}</p>
<p><strong>Encounter Date:</strong> {encounterDate:MMMM d, yyyy}</p>
<p><strong>Attending Physician:</strong> Dr. Sarah Johnson, MD</p>
v>
class='section'>
<h2>Chief Complaint</h2>
<p>Patient presented with acute respiratory symptoms including shortness of breath and persistent cough.</p>
v>
class='section'>
<h2>Hospital Course</h2>
<p>Patient was admitted for observation and treatment. Symptoms improved with standard protocol...</p>
v>
class='section'>
<h2>Discharge Instructions</h2>
<ul>
<li>Continue prescribed medications as directed</li>
<li>Follow up with primary care physician within 7 days</li>
<li>Return to ED if symptoms worsen</li>
</ul>
v>
class='footer'>
<p>Document generated: {DateTime.Now:yyyy-MM-dd HH:mm}</p>
<p>This document is archived in PDF/A-3a format for accessibility and long-term preservation.</p>
v>
;
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(clinicalDocumentHtml);
// Set comprehensive metadata for medical records management
var metadata = new System.Collections.Generic.Dictionary<string, string>
{
{ "Title", $"{documentType} - {patientId}" },
{ "Author", "Metro General Hospital EHR System" },
{ "Subject", $"Clinical documentation for patient {patientId}" },
{ "PatientMRN", patientId },
{ "DocumentType", documentType },
{ "Facility", facility },
{ "Department", department },
{ "EncounterDate", encounterDate.ToString("yyyy-MM-dd") },
{ "RetentionCategory", "Medical Record - Adult" },
{ "RetentionPeriod", "10 years from last encounter" }
};
pdf.MetaData.SetMetaDataDictionary(metadata);
// Embed clinical data (HL7 FHIR format)
string fhirData = @"{
sourceType"": ""DocumentReference"",
atus"": ""current"",
pe"": { ""text"": ""Discharge Summary"" },
bject"": { ""reference"": ""Patient/MRN-2026-00847"" }
byte[] fhirBytes = System.Text.Encoding.UTF8.GetBytes(fhirData);
var fhirConfig = new EmbedFileConfiguration(EmbedFileType.xml)
{
EmbedFileName = "clinical-data.json",
AFDesc = "FHIR DocumentReference metadata",
AFRelationship = AFRelationship.Data
};
var embedFiles = new List<EmbedFileByte>
{
new EmbedFileByte(fhirBytes, fhirConfig)
};
// Convert to PDF/A-3a (accessible archival with embedded data)
using var archivedRecord = pdf.ConvertToPdfA(embedFiles, PdfAVersions.PdfA3a);
string outputPath = $"medical-record-{patientId}-{encounterDate:yyyyMMdd}.pdf";
archivedRecord.SaveAs(outputPath);
Imports IronPdf
Imports System
Imports System.Collections.Generic
Imports System.Text
' Medical record metadata
Dim patientId As String = "MRN-2026-00847"
Dim documentType As String = "Discharge Summary"
Dim facility As String = "Metro General Hospital"
Dim department As String = "Internal Medicine"
Dim encounterDate As DateTime = New DateTime(2026, 2, 5)
' Create clinical document HTML
Dim clinicalDocumentHtml As String = $"
<!DOCTYPE html>
<html lang='en'>
<head>
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }}
.header {{ border-bottom: 2px solid #2c3e50; padding-bottom: 15px; margin-bottom: 20px; }}
.patient-info {{ background: #ecf0f1; padding: 15px; margin: 15px 0; }}
.section {{ margin: 20px 0; }}
h1 {{ color: #2c3e50; }}
h2 {{ color: #3498db; font-size: 14pt; }}
.footer {{ margin-top: 40px; font-size: 10pt; color: #666; }}
</style>
</head>
<body>
<div class='header'>
<h1>{facility}</h1>
<p>{department} | {documentType}</p>
</div>
<div class='patient-info'>
<p><strong>Patient ID:</strong> {patientId}</p>
<p><strong>Encounter Date:</strong> {encounterDate:MMMM d, yyyy}</p>
<p><strong>Attending Physician:</strong> Dr. Sarah Johnson, MD</p>
</div>
<div class='section'>
<h2>Chief Complaint</h2>
<p>Patient presented with acute respiratory symptoms including shortness of breath and persistent cough.</p>
</div>
<div class='section'>
<h2>Hospital Course</h2>
<p>Patient was admitted for observation and treatment. Symptoms improved with standard protocol...</p>
</div>
<div class='section'>
<h2>Discharge Instructions</h2>
<ul>
<li>Continue prescribed medications as directed</li>
<li>Follow up with primary care physician within 7 days</li>
<li>Return to ED if symptoms worsen</li>
</ul>
</div>
<div class='footer'>
<p>Document generated: {DateTime.Now:yyyy-MM-dd HH:mm}</p>
<p>This document is archived in PDF/A-3a format for accessibility and long-term preservation.</p>
</div>
</body>
</html>"
Dim renderer As New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf(clinicalDocumentHtml)
' Set comprehensive metadata for medical records management
Dim metadata As New Dictionary(Of String, String) From {
{"Title", $"{documentType} - {patientId}"},
{"Author", "Metro General Hospital EHR System"},
{"Subject", $"Clinical documentation for patient {patientId}"},
{"PatientMRN", patientId},
{"DocumentType", documentType},
{"Facility", facility},
{"Department", department},
{"EncounterDate", encounterDate.ToString("yyyy-MM-dd")},
{"RetentionCategory", "Medical Record - Adult"},
{"RetentionPeriod", "10 years from last encounter"}
}
pdf.MetaData.SetMetaDataDictionary(metadata)
' Embed clinical data (HL7 FHIR format)
Dim fhirData As String = "{
""resourceType"": ""DocumentReference"",
""status"": ""current"",
""type"": { ""text"": ""Discharge Summary"" },
""subject"": { ""reference"": ""Patient/MRN-2026-00847"" }
}"
Dim fhirBytes As Byte() = Encoding.UTF8.GetBytes(fhirData)
Dim fhirConfig As New EmbedFileConfiguration(EmbedFileType.xml) With {
.EmbedFileName = "clinical-data.json",
.AFDesc = "FHIR DocumentReference metadata",
.AFRelationship = AFRelationship.Data
}
Dim embedFiles As New List(Of EmbedFileByte) From {
New EmbedFileByte(fhirBytes, fhirConfig)
}
' Convert to PDF/A-3a (accessible archival with embedded data)
Using archivedRecord = pdf.ConvertToPdfA(embedFiles, PdfAVersions.PdfA3a)
Dim outputPath As String = $"medical-record-{patientId}-{encounterDate:yyyyMMdd}.pdf"
archivedRecord.SaveAs(outputPath)
End Using
End Using
輸出
對於電子健康記錄 (EHR) 系統,最有效的方法是在創建時將文件轉換為 PDF/A 格式——例如生成實驗室結果時、臨床記錄最終定稿時或出院總結時。 這種"創建時即歸檔"的策略避免了以後批量遷移的成本和複雜性。
後續步驟
以 PDF/A 格式歸檔文件並不一定很複雜。 IronPDF為.NET開發人員提供了一套完整的工具包,用於創建、轉換和豐富符合 PDF/A 標準的文件——所有這些都在熟悉的 C# 生態系統中完成。 無論您是從HTML產生存檔文件、為政府和醫療保健分發製作可存取的 PDF 、轉換舊版 PDF 以進行長期存儲,還是將外部驗證整合到大批量批次管道中, IronPDF都會處理技術細節,以便您可以專注於應用程式的需求。
從基礎的 PDF/A-1 標準到現代的 PDF/A-3 和 PDF/A-4 標準, IronPDF支援所有歸檔版本和符合性級別,包括 PDF/A-1a、1b、2a、2b、3a、3b、4、4e 和 4f。 專門的PDF/A 操作指南詳細介紹了轉換選項和符合性等級。 結合元資料管理、透過 EmbedFileConfiguration 進行文件嵌入以及ZUGFeRD/Factur-X 電子發票支持,它提供了滿足政府機構、法院系統、醫療保健機構和金融機構歸檔要求所需的一切。
準備開始歸檔了嗎? 下載IronPDF並免費試用。 如果您有任何疑問或想討論您的特定合規情況,請聯絡我們的工程支援團隊—我們很樂意協助您解決問題。
常見問題解答
什麼是PDF/A合規性?
PDF/A 合規性指的是符合 ISO 標準的 PDF 版本,該版本專為電子文件的歸檔和長期保存而設計。它確保文件在未來幾年內都能以相同的方式複製。
如何使用 C# 建立符合 PDF/A 標準的文件?
您可以使用 C# 和 IronPDF 庫創建符合 PDF/A 標準的文檔,該庫提供了強大的工具來產生 PDF 並將其轉換為各種 PDF/A 格式。
IronPDF支援哪些不同的PDF/A版本?
IronPDF 支援多種 PDF/A 版本,包括 PDF/A-1、PDF/A-2 和 PDF/A-3,每種版本都符合不同的文件歸檔和保存要求。
IronPDF 能否幫助嵌入 ZUGFeRD 和 Factur-X 等電子發票標準的來源資料?
是的,IronPDF 可以嵌入 ZUGFeRD 和 Factur-X 等電子發票標準的來源數據,以方便電子發票處理和合規性。
如何在 C# 中驗證 PDF/A 合規性?
您可以使用 IronPDF in C# 來驗證 PDF/A 合規性,並利用其內建的驗證工具來確保您的文件符合所需的 PDF/A 規格。
IronPDF 能否處理政府歸檔場景?
是的,IronPDF 能夠處理各種政府歸檔場景,包括符合美國國家檔案館 (NARA) 標準、法院文件和醫療記錄的要求。
使用 PDF/A 進行歸檔有哪些好處?
使用 PDF/A 進行歸檔的好處包括確保文件長期保存的完整性,提供標準化的格式以進行長期保存,並符合法律和組織要求。
IronPDF是否支援將現有PDF文件轉換為PDF/A格式?
IronPDF 支援將現有 PDF 轉換為 PDF/A 格式,方便合規性和長期文件保存。
IronPDF 如何確保 PDF/A 轉換過程中文件的完整性?
IronPDF 透過保持字體、影像和佈局的完整性,確保 PDF/A 轉換中的文件保真度,從而使存檔文件完全按照預期顯示。
我可以使用 IronPDF 進行醫療記錄歸檔嗎?
是的,IronPDF 可用於醫療記錄歸檔,有助於確保符合行業標準和文件保存法規。

