Technischer Artikel

Getaggte PDF-Figuren aus Excel-Bildern mit HotXLS

Wenn HotXLS ein Arbeitsblatt mit aktiviertem automatischen Tagging nach PDF exportiert, emittieren Arbeitsblatt-Bilder, die Alternativtext tragen, nun eigenständige /Figure-Strukturelemente mit einem Unicode-/Alt-Eintrag, dichten seitenlokalen Marked-Content-Kennungen und exakten Parent-Tree-Einträgen. Bilder ohne Alternativtext bleiben dekorative Artifacts, und Diagramme bleiben ebenfalls Artifacts. Dieser präzise Umfang wiegt schwer: Er macht informative Bilder für einen Screenreader erreichbar, und es ist nicht dasselbe wie volle PDF/UA-Konformität

Die Mechanik dahinter ist interessanter als die Feature-Beschreibung, denn zwei davon sind die Art von Detail, die still ein strukturell gültiges PDF produziert, dessen Struktur auf den falschen Inhalt zeigt

Was gilt als informatives Bild?

Nur ein nicht leerer AltText. Die Property TXLSXImage.AltText führt das OOXML-descr-Attribut der Non-Visual-Properties des Bildes im Round-Trip mit, und genau dort speichert Excel den Text, den ein Nutzer in das Alt-Text-Feld tippt. Das ist das einzige Signal in der Datei, dass der Autor das Bild als informationstragend statt dekorativ einschätzte, also ist es das einzige Signal, dem der Exporteur vertraut

Zwei Beinahe-Treffer werden bewusst nicht akzeptiert. Das Titelfeld, getrennt von der Beschreibung gespeichert, ist kein Ersatz: Ein Titel ist ein Name für das Objekt, nicht ein textliches Äquivalent von ihm, und ihn in /Alt zu befördern würde ein Dokument produzieren, das eine automatisierte Prüfung besteht, während es einem Screenreader „Bild 3“ ansagt. Eine leere Beschreibung ist auch keine Lücke, die ein Platzhalter füllen könnte; sie bedeutet, dass das Bild ein Artifact bleibt, was das korrekte Ergebnis für ein Logo oder eine Trennlinie ist. Diagramme bleiben vorerst ebenfalls Artifacts, denn das textliche Äquivalent eines Diagramms sind seine Daten, und eines aus den Reihen zu synthetisieren wäre Erfindung statt Extraktion

Bilder mit nicht leerem AltText exportieren als PDF-Figure-Strukturelemente mit eigener MCID; leere Beschreibungen und Diagramme bleiben Artifacts
Nur die Autorenbeschreibung in AltText signalisiert ein informatives Bild; ein Titel allein wird nie zum Alternativtext
uses
  lxHandleX, lxPDF;

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  Exporter: TXLSPDFExport;
  I: Integer;
begin
  Book := TXLSXWorkbook.Create;
  try
    Book.Open('regional-review.xlsx');
    Sheet := Book.Sheets.ByPos[0];

    // Vor dem Export prüfen: Ein Bild ohne Beschreibung
    // wird als dekoratives Artifact exportiert
    for I := 0 to Sheet.Images.Count - 1 do
      if Sheet.Images[I].AltText = '' then
        Sheet.Images[I].AltText := DescribeImage(Sheet.Images[I].Name);

    Exporter := TXLSPDFExport.Create;
    try
      Exporter.TagMode := xlsPdfTagsAutomatic;
      Exporter.DocumentLanguage := 'en-US';
      Exporter.SaveAsPDF(Sheet, 'regional-review.pdf');
    finally
      Exporter.Free;
    end;
  finally
    Book.Free;
  end;
end;

Warum braucht die Seite einen einzigen MCID-Zuteiler?

Weil der Parent Tree ein Array ist, das über die Marked-Content-Kennung indiziert wird, und zwei Zuteiler zwei Einträge produzieren, die denselben Platz beanspruchen. Getaggtes PDF verbindet Inhalt und Struktur in beide Richtungen. Auf der Inhaltsseite ist eine Spanne des Seiten-Content-Streams in BDC- und EMC-Operatoren verpackt, die eine /MCID-Nummer tragen, die innerhalb dieser Seite eindeutig ist. Auf der Strukturseite trägt das Seiten-Dictionary einen /StructParents-Schlüssel, der eine Zeile des Dokument-/ParentTree benennt, und diese Zeile ist ein Array, dessen Element am Index n das Strukturelement ist, das MCID n besitzt

Eine Arbeitsblattseite enthält Tabellenzellen und nun auch Figuren. Zählt der Zell-Tagger seine Kennungen ab null und der Figure-Tagger ebenfalls ab null, beansprucht die erste Figur den Platz, den die erste Zelle bereits besitzt. Nichts an der entstehenden Datei ist fehlerhaft genug, als dass ein Parser sie zurückweist: Der Strukturbaum ist intakt, der Marked Content ist ausgeglichen, und ein Validator sieht ein Dokument mit einem Parent Tree. Was ein Screenreader bekommt, ist eine Tabellenzelle, die als Bild angesagt wird, oder ein Bild, das mit dem Text einer Zelle angesagt wird. Der Exporteur teilt deshalb von einem einzigen Zähler auf Seitenebene zu, den beide Tagger gemeinsam nutzen, und friert den Seiten-Datensatz erst ein, wenn die Seitenobjektnummer bekannt ist, denn die Parent-Tree-Zeile lässt sich nicht schreiben, bevor die Seite, auf die sie sich bezieht, eine Identität hat

Unabhängige Zell- und Figure-Tagger kollidieren auf Parent-Tree-Platz null; ein MCID-Zähler auf Seitenebene hält jede Markierung auf einen Besitzer abgebildet
Die kollidierende Datei besteht weiterhin einen strukturellen Validator; nur die Screenreader-Ansage ist falsch

Die Figur muss die gesamte sichtbare Instanz umschließen

Die naive Platzierung ist, den Do-Operator zu umschließen, der das Bild-XObject aufruft, denn das ist der Operator, der das Bild zeichnet. Das reicht nicht. Ein Arbeitsblatt-Bild wird oft mit einem Schatten dahinter und einem Beschneidungspfad darum gezeichnet, und diese Markierungen sind Teil des sichtbaren Objekts. Außerhalb des /Figure-Geltungsbereichs gelassen werden sie zu unmarkiertem Inhalt, was exakt der Zustand ist, den eine Strukturprüfung anmarkt

Der Marked-Content-Geltungsbereich öffnet sich also vor dem Schatten und schließt nach dem Bildzeichnen, und umfasst auch den Clip. Teilen bleibt bewahrt, wo Teilen korrekt ist: Zwei Zellen, die dieselbe Bild-Nutzlast zeigen, referenzieren weiterhin ein einziges Bild-XObject, denn das ist eine Optimierung auf Ressourcenebene und hat nichts mit Semantik zu tun. Was jede sichtbare Instanz bekommt, ist ihre eigene MCID und ihr eigenes Strukturelement, denn zwei Vorkommen desselben Logos an verschiedenen Orten sind zwei Dinge, die ein Leser antrifft. Bildplatzierung und die EMU-Geometrie, die diese Objekte positioniert, behandelt der Artikel zur Bildgeometrie

Die BDC-Markierung öffnet den Figure-Geltungsbereich vor Schatten und Clip, und EMC schließt nach dem Do-Bildzeichnen, ganz über die sichtbare Instanz
Nur den Bildoperator zu umschließen ließe Schatten und Clip als unmarkierten Inhalt zurück; Ressourcenteilen zwischen Zellen bleibt bewahrt

Lesereihenfolge auf einer Arbeitsblattseite

Die Lesereihenfolge ist eine Entscheidung, die der Exporteur treffen muss, denn eine Tabelle hat keinen verfassten Fluss wie ein Dokument. Die gewählte Regel ist stabil und leicht zu erklären: Je Seite kommt zuerst die Tabelle, dann die Figuren in Zeichnenreihenfolge. Ein Leser hört also den tabellarischen Inhalt der Seite und dann ihre Bilder, statt Bilder verschränkt an der Position zu bekommen, die die Zeichnungsobjekte zufällig in der Datei einnahmen

Diese Reihenfolge gilt je Seite statt je Dokument, was bei einer Arbeitsmappe zählt, die in Dutzende Seiten paginiert: Der Strukturzweig jeder Seite ist in sich geschlossen, also springt ein Leser, der zwischen Seiten wechselt, nicht in eine frühere Tabelle zurück. Wer Kontrolle darüber braucht, wie das Blatt überhaupt paginiert, dem ist die Interaktion von Seiteneinrichtung und Druckbereich beschrieben in dem Artikel zu Schutz und Seiteneinrichtung

Was das bescheinigt und was nicht

Es bescheinigt, dass informative Bilder die Hilfstechnologie mit ihrer vom Autor gelieferten Beschreibung erreichen, und dass die Inhalt-zu-Struktur-Zuordnung korrekt ist statt bloß vorhanden. Es macht die Ausgabe nicht PDF/UA-konform, und es so zu beschreiben wäre eine Behauptung, die die Implementierung nicht stützen kann: Diagramme sind weiterhin Artifacts, und eine vollständige Konformitätserklärung verlangt eine Prüfung jedes Strukturtyps, jeder Schrift und der Dokumentmetadaten als Ganzem

Ist Ihre Anforderung ein Archiv- oder Konformitätsprofil statt einer Verbesserung der Barrierefreiheit, ist das eine andere Exportkonfiguration und ein anderer Satz Prüfungen, beschrieben in dem Artikel zum PDF/A-Archivexport. Beides kombiniert sich, aber sie antworten verschiedenen Prüfern

Ein praktischer Vorschlag für eine Berichtspipeline: Alternativtext dort prüfen, wo die Arbeitsmappe erzeugt wird, nicht zur Exportzeit. Der Generator weiß, was jedes Diagrammbild oder eingebettete Schaubild darstellt, und kann eine echte Beschreibung in AltText schreiben; ein Durchlauf zur Exportzeit kann nur sagen, dass eine Beschreibung fehlt. HotXLS liest und schreibt XLS, XLSX, ODS und CSV nativ aus Delphi und C++Builder ohne Excel-Abhängigkeit, und seine Exportkonfigurationsoptionen listet die Produktseite der HotXLS Delphi Tabellenkomponente