Техническая статья

PDFlibPas: PDF/A and PDF/UA preflight в Delphi

losLab PDF Library предоставляет командам Delphi и C++Builder PDF-движок с доступным исходным кодом для настольных, серверных, DLL, ActiveX и Dylib процессов, включая встроенные проверки PDF/A и PDF/UA, подписи PAdES и выбор рендерера без отправки документов во внешний PDF-сервис.

Эта статья предназначена для developers delivering archive-ready and accessibility-aware PDFs from Delphi systems. Она рассматривает PDF/A and PDF/UA preflight как промышленную инженерию документов, а не как одиночный вызов компонента.

Практический риск состоит в том, что PDF/A and PDF/UA failures usually reflect document design decisions, so late preflight without ownership produces lists of issues nobody can fix. Поэтому процессу нужны письменный контракт, наблюдаемая диагностика и реалистичные регрессионные файлы.

Архитектурные решения

Connect preflight findings to template ownership. target PDF/A profile, PDF/UA expectations, and accepted validator set / font, metadata, color, annotation, form, and attachment policies

  • target PDF/A profile, PDF/UA expectations, and accepted validator set
  • font, metadata, color, annotation, form, and attachment policies
  • tag structure, heading order, table markup, alternate text, and artifacts
  • issue ownership and release-gate severity mapping

Порядок реализации

Treat diagnostics as product requirements. The order below keeps the workflow reviewable for Delphi and C++Builder teams.

  1. configure document generation around the target profiles before output
  2. run structured preflight and normalize findings by owner and severity
  3. route template issues to template maintainers and data issues to application owners
  4. rerun validation after each fix rather than relying on visual inspection
  5. ship the report with the document package when customers require evidence

Доказательства проверки

Preflight evidence for archive and accessibility workflows. Keep these fields with the output or support record.

  • profile, validator version, issue code, severity, page, object, and owner
  • font embedding, output intent, metadata, and attachment findings
  • tagging diagnostics such as heading order, table structure, artifacts, and alternate text
  • release decision, waivers, and final pass or fail report

Archive and accessibility profiles ask different questions

PDF/A focuses on durable reproduction while PDF/UA focuses on semantic access. A production workflow should keep both validation profiles visible and assign findings to generation code, templates, or content owners.

Вопросы для проверки перед выпуском

Перед выпуском в production команда должна уметь ответить на эти вопросы без чтения исходного кода

  • Who owns target PDF/A profile, PDF/UA expectations, and accepted validator set?
  • What evidence proves profile, validator version, issue code, severity, page, object, and owner?
  • What happens when an archive-valid file can still have poor reading order?
  • Which regression file covers ship the report with the document package when customers require evidence?

Замечания для инженерного ревью по PDF/A and PDF/UA preflight

Используйте эти замечания, чтобы убедиться, что функция вышла за рамки демо и может быть обоснована на релизе, в поддержке и при эскалации клиента

  • Решение: target PDF/A profile, PDF/UA expectations, and accepted validator set. Точка приложения при реализации: run structured preflight and normalize findings by owner and severity. Доказательство приемки: tagging diagnostics such as heading order, table structure, artifacts, and alternate text. Триггер регрессии: third-party inserted pages can break profile assumptions late in assembly
  • Решение: font, metadata, color, annotation, form, and attachment policies. Точка приложения при реализации: route template issues to template maintainers and data issues to application owners. Доказательство приемки: release decision, waivers, and final pass or fail report. Триггер регрессии: an archive-valid file can still have poor reading order
  • Решение: tag structure, heading order, table markup, alternate text, and artifacts. Точка приложения при реализации: rerun validation after each fix rather than relying on visual inspection. Доказательство приемки: profile, validator version, issue code, severity, page, object, and owner. Триггер регрессии: decorative content should be marked as artifacts instead of hidden visually only
  • Решение: issue ownership and release-gate severity mapping. Точка приложения при реализации: ship the report with the document package when customers require evidence. Доказательство приемки: font embedding, output intent, metadata, and attachment findings. Триггер регрессии: forms and annotations can conflict with archive goals depending on profile

Пограничные случаи

  • an archive-valid file can still have poor reading order
  • decorative content should be marked as artifacts instead of hidden visually only
  • forms and annotations can conflict with archive goals depending on profile
  • third-party inserted pages can break profile assumptions late in assembly

Примечания по Delphi / C++Builder

PDFlibPas should sit behind a small service boundary that receives files, streams, profiles, and credentials, then returns output paths, warnings, metrics, and validation status. Важные термины включают PDF/A, PDF/UA, CreatePreflightReportEx, accessibility, tag structure, validator.

Пример кода Delphi

Следующий эскиз Delphi показывает практическую границу сервиса для этой темы. Оставляйте проверки политики, журналирование и валидацию вне узкого блока вызова продукта, чтобы сценарий было проще тестировать.

procedure RunStandardsPreflight(const InputFile, ReportFile: string; const Profile: string);
var
  Pdf: TPDFlib;
begin
  Pdf := TPDFlib.Create;
  try
    Pdf.LoadFromFile(InputFile, '');
    TFile.WriteAllText(ReportFile, BuildStandardsReport(Pdf, Profile), TEncoding.UTF8);
    FailOnBlockingStandardsIssues(ReportFile);
  finally
    Pdf.Free;
  end;
end;

Производственный чек-лист

  • Запускайте сценарий на пустом файле, обычном клиентском файле и файле худшего случая
  • Открывайте сгенерированный PDF в целевом просмотрщике, валидаторе, принтере или downstream-приложении
  • Записывайте версию продукта, версию профиля, хэш входа, путь вывода, затраченное время и число предупреждений
  • Храните пароли, сертификаты, временные файлы и данные клиентов по явным правилам хранения
  • Добавляйте регрессионные документы, когда клиентский файл выявляет новый граничный случай

Документация по продукту

PDFlibPas

Дополнительные примеры кода

var
  Pdf: TPDFlib;
  Diag: WideString;
begin
  Pdf := TPDFlib.Create;
  try
    Pdf.NewDocument;
    Pdf.SetPDFAMode(1);
    Pdf.LoadOutputIntentProfile('sRGB-IEC61966-2.1.icc', 'RGB');
    Pdf.SetPDFUAMode('en-US');
    Pdf.SetInformation(1, 'Quarterly Statement');  // /Title: required for PDF/UA
    // ... draw tagged content here ...
    Diag := Pdf.GetPDFUADiagnostics;
    if Diag <> '' then
      Writeln('fix before shipping: ', Diag);
    Pdf.SaveToFile('statement.pdf');
    // the preflight that counts runs on the saved file:
    Writeln(Pdf.CreatePreflightReport('statement.pdf', '', 1, 0));
  finally
    Pdf.Free;
  end;
end;