Articolo tecnico

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

Questa versione localizzata affronta PDF/A and PDF/UA Preflight in Delphi with PDFlibPas usando l'articolo inglese aggiornato come riferimento tecnico per team Delphi, PDF e software documentale

La pagina trasforma la base aggiornata in punti di controllo pratici per progettazione, implementazione e validazione

Contenuto sincronizzato dalla base inglese

L'articolo di base è stato ampliato con contesto operativo, decisioni tecniche ed esempi concreti, quindi questa pagina va letta come guida di lavoro e non come breve riepilogo

Punti importanti della versione aggiornata:

  • Usare prima file di input piccoli e riproducibili
  • Mantenere invariati nomi di prodotto, API, file e valori literal
  • Salvare output del validatore e versioni insieme al file di prova generato

Scelte pratiche di implementazione

Partire dal tipo di file, dal risultato atteso e dallo stato di errore visibile all'utente. Collegare poi ogni chiamata API a un risultato verificabile, così validazione, log e supporto possono riprodurre il caso del cliente

  • Usare prima file di input piccoli e riproducibili
  • Mantenere invariati nomi di prodotto, API, file e valori literal
  • Salvare output del validatore e versioni insieme al file di prova generato

Codice e punti API

Gli esempi di codice restano invariati per poterli confrontare direttamente con progetti Delphi, C++Builder e Lazarus/FPC

function GateArchiveUpload(Pdf: TPDFlib; const FileName: string): Boolean;
var
  ListId, I: Integer;
begin
  ListId := Pdf.CheckFileCompliance(FileName, '', 1, 0);  // 1 = PDF/A
  if ListId = 0 then
  begin
    // 0 means "no findings" OR "file unreadable" -- disambiguate before passing
    Result := Pdf.LastErrorCode = 0;
    Exit;
  end;
  for I := 0 to Pdf.GetStringListCount(ListId) - 1 do
    LogFinding(FileName, Pdf.GetStringListItem(ListId, I));
  Pdf.ReleaseStringList(ListId);
  Result := False;
end;
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;

Controllo prima della pubblicazione

Verificare il file di output con gli stessi strumenti che userà il cliente o l'archivio. Annotare versione del componente, dati di test, versione del validatore e risultato osservato

Note di revisione per la produzione

Questa sezione aggiuntiva porta l'esempio in un contesto di integrazione reale. Prima di spostare il codice in produzione, chiarire quale documento entra nel flusso, quale componente lo genera o lo legge, quale output deve ricevere l'utente e quali valori devono rimanere invariati tra Delphi, C++Builder e strumenti esterni

Verificare il comportamento con file piccoli, input danneggiati e dati simili a quelli dei clienti. Problemi di font, pagine, cifratura, metadati o codifica emergono spesso solo quando il caso include nomi lunghi, caratteri internazionali, oggetti annidati e valori vuoti

Se il flusso gira in un servizio o in un batch, aggiungere controlli per rilascio delle risorse, riutilizzo dei componenti, gestione delle eccezioni e log della causa di rifiuto. Il risultato deve essere chiaro: file creato, file rifiutato con motivo comprensibile o operazione ritentabile in sicurezza