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

เอาต์พุต 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 ตามปกติ และห้ามการเข้ารหัส — ไฟล์เก็บถาวรที่เข้ารหัสเป็นความขัดแย้งที่มาตรฐานไม่รับ

เมทริกซ์ค่าตัวเลือก PDF/A-4 ใน HotPDF แสดงฐาน 4 ที่ไม่มีตัวอักษรบ่งชี้ความสอดคล้อง คู่กับโปรไฟล์ 4E ฝ่ายวิศวกรรมและ 4F ไฟล์ฝัง บนเงื่อนไขร่วมของ PDF 2.0
ค่าพื้นฐาน '4' เขียน part 4 rev 2020 โดยไม่มีตัวอักษรกำกับเลย มีเพียง 4E และ 4F เท่านั้นที่ยังคงมี
var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := 'invoice-archive.pdf';
    Pdf.PDFACompliance := '4F';   // PDF/A-4f: associated files ในรูปแบบใดก็ได้
    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 เดียวแทนที่จะสุมซ้อน

แผนภาพเปรียบเทียบคำศัพท์ role แบบแบนของ PDF/UA-1 กับ namespace ของ PDF/UA-2 ที่ผูกผ่าน RegisterStructureNamespace และ AddStructureElementNS ใน Delphi
URI หนึ่งค่าใช้พจนานุกรม namespace ชุดเดียวซ้ำตลอดเสมอ — ไม่มีกองซ้ำซ้อน
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 หลายสัปดาห์ให้หลังที่มีคนส่งต่อมาจากลูกค้า

ขั้นตอนประตูตรวจ structure-tree สี่ด่านที่ HotPDF ตรวจที่ EndDoc: ราก Document เดียว, namespace dictionary สะอาด, reference NS ที่ resolve ได้ และ role มาตรฐานหรือที่แมปแล้ว
ถ้าไปดักประตูเหล่านี้เร็วกว่านั้น จะกลายเป็นปฏิเสธสถานะระหว่างกลางที่ถูกต้อง

บทบาท 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 ที่รองรับ