บทความเทคนิค

เอาต์พุต PDF 2.0 PDF/A-4 และ PDF/UA-2 ด้วย HotPDF ใน Delphi

HotPDF เขียนเอกสาร PDF 2.0 พื้นเมืองจาก Delphi และ C++Builder รวมถึงโปรไฟล์เก็บถาวร PDF/A-4 สามแบบ และเอาต์พุตที่เข้าถึงได้แบบ PDF/UA-2 พร้อมองค์ประกอบโครงสร้างที่มีเนมสเปซ การเลือกใช้พวกมันเป็นเรื่องของสองคุณสมบัติ แต่มาตรฐานเบื้องหลังคุณสมบัตินั้นเปลี่ยนไปมากกว่าที่เลขเวอร์ชันบอก PDF/A-4 ทิ้ง conformance letter ที่ทุกคนเรียนรู้กับ PDF/A-2 และ PDF/UA-2 แนะนำเนมสเปซโครงสร้างที่เอกสาร part 1 ไม่เคยมี

บทความนี้ครอบคลุมสิ่งที่เปลี่ยนจริงในไฟล์ที่ผลิต และข้อผิดพลาดใดที่ HotPDF เปลี่ยนเป็น exception ที่ EndDoc แทนที่จะเป็นเอกสารที่ตก validation ที่ไซต์ของลูกค้า

การระบุ PDF/A-4 ต่างจาก part 2 และ 3 อย่างไร

PDF/A-4 ระบุตัวเองด้วยหมายเลข part และปี revision โดยไม่มี conformance letter สำหรับ base part ตั้ง PDFACompliance เป็น '4' แล้ว HotPDF ปล่อย pdfaid:part=4 พร้อม pdfaid:rev=2020 และไม่มี entry pdfaid:conformance เลย letter ไม่ได้หายไป — part 4 ไม่มีระดับ A/B/U เพราะข้อกำหนดที่ครั้งหนึ่งแยกพวกมันถูกพับเข้าไปใน base part

สองส่วนขยายยังคงมี letter '4E' เลือก PDF/A-4e สำหรับเอกสารวิศวกรรมและปล่อย conformance E ซึ่งอนุญาตเส้นทาง annotation 3D และ RichMedia ที่โปรไฟล์อื่นห้าม '4F' เลือก PDF/A-4f และปล่อย conformance F ซึ่งอนุญาตไฟล์ฝังรูปแบบใดก็ได้ ทั้งสามบังคับ header PDF 2.0 กำหนด output intent และการตรวจสอบเมตาดาต้า PDF/A ตามปกติ และห้ามการเข้ารหัส — ไฟล์เก็บถาวรที่เข้ารหัสเป็นความขัดแย้งที่มาตรฐานไม่รับ

var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := 'invoice-archive.pdf';
    Pdf.PDFACompliance := '4F';   // PDF/A-4f: associated files of any format
    Pdf.BeginDoc;
    Pdf.CurrentPage.SetFont('Arial', [], 11);
    Pdf.CurrentPage.TextOut(50, 760, 0, 'Invoice 2026-0731');
    Pdf.AddPDFAssociatedFile('invoice.xml', 'text/xml',
      'Structured invoice data', 'Data', LoadInvoiceBytes);
    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

AddPDFAssociatedFile ฝังไฟล์ สร้าง FileSpec พร้อม /AFRelationship และลงทะเบียนมันทั้งใน array /AF ของ Catalog และ EmbeddedFiles name tree การลงทะเบียนทั้งสองเป็นข้อกำหนด ไฟล์ที่อยู่ในเพียงฝั่งเดียวคือเหตุผลที่พบบ่อยที่สุดที่ทำให้ใบแจ้งหนี้แบบไฮบริดผ่านการตรวจสายตาแต่ตกตัวตรวจสอบจริง relationship string รับ Source, Data, Alternative, Supplement หรือ Unspecified และโปรไฟล์ที่ใช้อยู่ต้องเป็น PDF/A-3, PDF/A-4e หรือ PDF/A-4f — base part 4 ไม่รับ associated file ชื่อเดิม AddPDFA3AssociatedFile ยังคงทำงานสำหรับโค้ดที่มีอยู่

สิ่งที่ PDF/UA-2 เรียกร้องที่ PDF/UA-1 ไม่ได้

PDF/UA-2 บังคับ PDF 2.0 และปล่อย pdfuaid:part=2 พร้อม pdfuaid:rev=2024 และแนะนำเนมสเปซเข้าสู่ structure tree เอกสาร part 1 มีคลังคำศัพท์มาตรฐานที่แบนราบเพียงชุดเดียว เอกสาร part 2 สามารถพกบทบาทที่กำหนดเองได้ตราบใดที่แต่ละบทบาทอยู่ในเนมสเปซที่ประกาศแล้ว ซึ่งเป็นสิ่งที่ทำให้การติดแท็กเฉพาะโดเมนอ่านได้ด้วยเทคโนโลยีช่วยเหลือแทนที่จะเป็นการเดา

สองเมธอดทำงานนี้ RegisterStructureNamespace สร้างหรือใช้ซ้ำ dictionary /Type /Namespace แบบ indirect และจัดประเภทมันใน StructTreeRoot /Namespaces คืนค่า dictionary ให้คุณใช้ซ้ำ AddStructureElementNS สร้างองค์ประกอบโครงสร้างที่ entry /NS ชี้ไปที่ dictionary นั้น ซึ่งเป็นสิ่งที่อนุญาตให้ชื่อบทบาทอยู่นอกชุดมาตรฐานได้ การเรียกซ้ำด้วย URI เดียวกันจะใช้ dictionary เดียวแทนที่จะสุมซ้อน

var
  Root: THPDFDictionaryObject;
begin
  Pdf.PDFUACompliance := True;
  Pdf.PDFUAPart := 2;             // part 2 forces PDF 2.0
  Pdf.Lang := 'en-US';
  Pdf.BeginDoc;
  Root := Pdf.AddStructureElement('Document', nil);
  Pdf.AddStructureElementNS('WidgetGroup',
    'https://example.com/ns/widgets', Root);
  Pdf.EndDoc;
end;

Lang ไม่ใช่ของประดับตรงนี้ เอกสาร tagged ที่ไม่ประกาศภาษาธรรมชาติทิ้งให้ตัวอ่านหน้าจอเดาการออกเสียง และ PDF/UA ถือการละเว้นนั้นเป็นข้อบกพร่อง ไม่ใช่ความชอบ

ข้อผิดพลาดโครงสร้างใดบ้างที่ EndDoc จับได้

สี่ข้อ และแต่ละข้อสอดคล้องกับเอกสารที่มิฉะนั้นจะถึงตัวตรวจสอบด้วยสภาพพัง structure root ต้องมีองค์ประกอบ Document ระดับบนสุดเพียงตัวเดียว ทุก dictionary เนมสเปซต้องเป็น indirect, พิมพ์เป็น Namespace, และพก URI ที่ไม่ซ้ำและไม่ว่าง ทุกการอ้างอิง /NS ขององค์ประกอบโครงสร้างต้องคลี่คลายไปยัง dictionary ที่อยู่ใน array /Namespaces ของ root จริง ๆ และบทบาทที่ไม่มีเนมสเปซต้องเป็นบทบาทมาตรฐาน PDF 2.0 หรือคลี่คลายผ่าน RoleMap

สิ่งเหล่านี้ทำงานที่ EndDoc เพราะนั่นคือช่วงเวลาสุดท้ายที่ต้นไม้ทั้งหมดยังอยู่ในหน่วยความจำและเป็นช่วงแรกที่มันสมบูรณ์ การจับก่อนหน้านั้นหมายถึงการปฏิเสธสถานะกลางที่ถูกต้อง การจับภายหลังหมายถึงไม่จับเลย ผลลัพธ์เชิงปฏิบัติต่อโค้ดของคุณคือบั๊กโครงสร้างปรากฏที่ท้ายการสร้างพร้อมข้อความระบุปัญหา แทนที่จะปรากฏเป็นรายงาน veraPDF หลายสัปดาห์ให้หลังที่มีคนส่งต่อมาจากลูกค้า

บทบาท PDF 2.0 ที่ควรรู้จัก

enum บทบาทแบบพิมพ์เพิ่ม DocumentFragment, Aside, Title, FENote, Sub, Em, Strong และ Artifact สามตัวในนั้นเปลี่ยนวิธีที่คุณติดแท็กเอกสารธุรกิจทั่วไป Aside ให้บ้านที่เหมาะสมแก่ sidebar และ pull quote ในที่สุด แทน Sect ที่ใช้ผิดวัตถุประสงค์ FENote ทำเครื่องหมายเชิงอรรถและอรรถท้ายเล่มว่าเป็นสิ่งที่มันเป็น ทำให้ตัวอ่านเสนอมันได้แทนที่จะสอดแทรกกับเนื้อหา Em และ Strong แทนการเดาเชิงความหมายที่เคยมาจากการติดแท็กการเน้นเป็นการจัดรูปแบบระดับ span

overload แบบสตริงยังรับรูปแบบ Hn แบบเปิด รวมถึง H7 ขึ้นไป PDF 1.7 หยุดที่ H6 ซึ่งบังคับให้เอกสารเทคนิคที่ลึกต้องทำเค้าโครงให้แบนหรือใช้ระดับซ้ำ หากคุณผลิตเอกสารมาตรฐาน ประมวลกฎหมาย หรือแคตตาล็อกชิ้นส่วน สิ่งนี้อย่างเดียวอาจเป็นเหตุผลที่จะย้ายเอาต์พุตไป PDF 2.0

สิ่งที่ควรตรวจก่อนสลับเอาต์พุตการผลิต

PDF 2.0 เป็นการเปลี่ยน header ที่มีผลยาวนาน เครื่องมือนำเข้าคลังเก็บเก่า ๆ, RIP ของแท่นพิมพ์บางตัว และตัวอ่าน line-of-business จำนวนที่น่าประหลาดใจรับเพียงถึง PDF 1.7 และพวกมันล้มเหลวที่ header แทนที่จะเป็นสิ่งใดที่คุณทำผิด ก่อนสลับ ให้ยืนยันระบบที่บริโภค และจำไว้ว่าการเลือกโปรไฟล์ PDF/A-4 คือการเลือก PDF 2.0 ไม่ว่าคุณจะขอหรือไม่

ลำดับที่ปลอดภัยคือรักษา PDF/A-3 สำหรับเอกสารที่ส่งออกไปยังผู้อ่านที่ไม่รู้จัก ใช้ PDF/A-4f สำหรับคลังเก็บภายในที่คุณควบคุมการนำเข้า และนำ PDF/UA-2 มาใช้เฉพาะที่นโยบายการเข้าถึงระบุ หากคุณกำลังทำงานฝั่งเก็บถาวรก่อน คู่มือ การตรวจสอบ PDF/A, PDF/X และ PDF/UA และ ใบแจ้งหนี้ไฮบริด ZUGFeRD และ Factur-X บน PDF/A-3 ครอบคลุมการเลือกโปรไฟล์ที่สำคัญก่อนเลขเวอร์ชัน และบันทึกของ การรายงาน preflight อัตโนมัติ แสดงวิธีทำให้คำตัดสินเป็นส่วนหนึ่งของบิลด์ของคุณแทนที่จะเป็นขั้นตอนด้วยมือ

HotPDF จัดส่งพื้นผิวการเขียน PDF 2.0 ทั้งหมดเป็นโค้ด VCL พื้นเมืองสำหรับ Delphi และ C++Builder ดังนั้นเอาต์พุต PDF/A-4 และ PDF/UA-2 จึงไม่ต้องมีเอนจินหรือ redistributable ภายนอก — หน้าคอมโพเนนต์ HotPDF จัดประเภทโปรไฟล์และเวอร์ชัน RAD Studio ที่รองรับ