Techninis straipsnis

Pažymėti PDF paveikslai iš Excel atvaizdų su HotXLS

Kai HotXLS eksportuoja darbalapį į PDF su įjungtu automatiniu žymėjimu, darbalapio paveikslai, nešantys alternatyvųjį tekstą, dabar skleidžiasi kaip nepriklausomi /Figure struktūros elementai su Unicode /Alt įrašu, tankiais puslapio vietiniais pažymėto turinio identifikatoriais ir tiksliais pirmtakų medžio įrašais. Paveikslai be alternatyviojo teksto lieka dekoratyviniais artefaktais, ir diagramos taip pat lieka artefaktais. Ta tiksli taikymo sritis svarbi: ji padaro informacinius atvaizdus pasiekiamus ekrano skaitytuvui, ir tai nėra tas pats, kas pilnas PDF/UA atitikimas

Mechanika už jos yra įdomesnė už savybės aprašymą, nes dvi iš jų yra tokios detalės rūšis, kuri tyloje pagamina struktūriškai teisėtą PDF, kurio struktūra rodo į neteisingą turinį

Kas laikoma informaciniu atvaizdu?

Tik netuščias AltText. TXLSXImage.AltText savybė abipusiai perneša OOXML descr atributą paveikslo nevaizdinėms savybėms, kur Excel saugo tekstą, kurį vartotojas įrašo į alt teksto sritį. Tai vienintelis faile esantis signalas, kad autorius paveikslą laikė nešančiu informaciją, o ne dekoraciją, todėl tai vienintelis signalas, kuriuo eksportuotojas pasitiki

Dvi beveik tinkamos alternatyvos sąmoningai nepriimamos. Antraštės laukas, saugomas atskirai nuo aprašymo, nėra pakaitalas: antraštė yra objekto vardas, o ne jo tekstualus atitikmuo, ir jos kilvinimas į /Alt pagamintų dokumentą, išlaikantį automatinę patikrą, bet skelbiantį „Picture 3“ ekrano skaitytuvui. Tuščias aprašymas taip pat nėra spraga, kurią užpildyti vietos ženklu; jis reiškia, kad atvaizdas lieka artefaktu, kas yra teisingas rezultatas logotipui ar skiriamajai linijai. Diagramos kol kas taip pat lieka artefaktais, nes diagramos tekstualus atitikmuo yra jos duomenys, ir vieno sintetinimas iš eilučių būtų išradimas, o ne ištraukimas

Paveikslai su netuščiu AltText eksportuojami kaip PDF Figure struktūros elementai su savu MCID; tušti aprašymai ir diagramos lieka artefaktais
Tik autoriaus aprašymas AltText signalizuoja informacinį atvaizdą; viena antraštė niekada netampa alt tekstu
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];

    // Auditas prieš eksportą: atvaizdas be aprašymo
    // bus eksportuotas kaip dekoratyvinis artefaktas
    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;

Kodėl puslapiui reikia vieno MCID skirstytojo?

Nes pirmtakų medis yra masyvas, indeksuotas pažymėto turinio identifikatoriumi, o du skirstytojai pagamina du įrašus, teigiančius tą patį lizdą. Pažymėtas PDF jungia turinį su struktūra abiem kryptimis. Turinio pusėje puslapio turinio srauto iškarpa apvyniojama BDC ir EMC operatoriais, nešančiais /MCID numerį, unikalų tame puslapyje. Struktūros pusėje puslapio žodynas neša /StructParents raktą, įvardijantį dokumento /ParentTree eilutę, o ta eilutė yra masyvas, kurio elementas indekse n yra struktūros elementas, valdantis MCID n

Darbalapio puslapis turi lentelės langelių ir, dabar, paveikslų. Jeigu langelių žymeklis skaičiuoja savo identifikatorius nuo nulio ir paveikslų žymeklis irgi skaičiuoja nuo nulio, pirmasis paveikslas užima lizdą, kurį jau valdo pirmasis langelis. Nieko gautajame faile nėra pakankamai sugadinta, kad analizatorius atmestų: struktūros medis sveikas, pažymėtas turinys subalansuotas, o tikrintojas mato dokumentą su pirmtakų medžiu. Tai, ką gauna ekrano skaitytuvas, yra lentelės langelis, skelbiamas kaip atvaizdas, arba atvaizdas, skelbiamas su langelio tekstu. Eksportuotojas todėl skirsto iš vieno puslapio lygio skaitiklio, bendro abiem žymekliams, ir užšaldo puslapio įrašą tik tada, kai žinomas puslapio objekto numeris, nes pirmtakų medžio eilutės negalima rašyti, kol puslapis, kurį ji nurodo, neturi tapatybės

Nepriklausomi langelių ir paveikslų žymekliai susiduria pirmtakų medžio lizde nulis; vienas puslapio lygio MCID skaitiklis laiko kiekvieną žymę priskirtą vienam valdytojui
Susiduriantis failas vis tiek išlaiko struktūrinį tikrintoją; neteisingas tik ekrano skaitytuvo pranešimas

Figure privalo apvynioti visą matomą egzempliorių

Naivi padėtis — apvynioti Do operatorių, kviečiantį atvaizdo XObject, nes tai operatorius, piešiantis paveikslą. To neužtenka. Darbalapio paveikslas dažnai piešiamas su šešėliu už jo ir iškarpos keliu aplink jį, ir tie žymės yra matomo objekto dalis. Paliktos už /Figure apimties ribų jos tampa nepažymėtu turiniu — būtent ta būsena, kurią pažymi struktūros auditas

Taigi pažymėto turinio apimtis atsidaro prieš šešėlį ir užsidaro po atvaizdo piešimo, dengdama ir iškarpą. Dalijimasis išsaugomas ten, kur dalijimasis teisingas: du langeliai, rodantys tą patį paveikslo turinį, vis tiek nurodo vieną atvaizdo XObject, nes tai išteklių lygio optimizacija ir neturi nieko bendro su semantika. Ką gauna kiekvienas matomas egzempliorius — savą MCID ir savą struktūros elementą, nes du to paties logotipo pasirodymai skirtingose vietose yra du dalykai, kuriuos sutinka skaitytojas. Atvaizdų išdėstymas ir EMU geometrija, pozicionuojanti šiuos objektus, dengiama atvaizdų geometrijos straipsnyje

BDC žymė atveria Figure apimtį prieš šešėlį ir iškarpą, o EMC uždaro po Do atvaizdo piešimo, dengdama visą matomą egzempliorių
Vieno atvaizdo operatoriaus apvyniojimas paliktų šešėlį ir iškarpą kaip nepažymėtą turinį; išteklių dalijimasis tarp langelių išsaugomas

Skaitymo tvarka darbalapio puslapyje

Skaitymo tvarka yra sprendimas, kurį eksportuotojas privalo priimti, nes skaičiuoklė neturi autoriaus parašyto srauto, koks yra dokumente. Priimta taisyklė stabili ir lengvai paaiškinama: kiekvienam puslapiui pirma eina lentelė, tada paveikslai piešimo tvarka. Skaitytojas todėl girdi puslapio lentelinį turinį, o paskui jo atvaizdus, o ne atvaizdus, įpintus bet kurioje pozicijoje, kurią braižymo objektai atsitiktinai užėmė faile

Ta tvarka yra pagal puslapį, o ne pagal dokumentą, kas svarbu darbo knygai, puslapiuojančiai į dešimtis puslapių: kiekvieno puslapio struktūros šaka savarankiška, todėl skaitytojas, keliantis tarp puslapių, nesušoka atgal į ankstesnę lentelę. Jeigu reikia valdyti, kaip lapas apskritai puslapiuoja, puslapio sąrangos ir spaudinio srities sąveika aprašyta apsaugos ir puslapio sąrangos straipsnyje

Ką tai sertifikuotų, ir ko nesertifikuotų

Ji sertifikuotų, kad informaciniai paveikslai pasiekia pagalbinę technologiją su autoriaus pateiktu aprašymu, ir kad turinio į struktūrą atvaizdis teisingas, o ne tik egzistuoja. Ji nepadaro išvesties PDF/UA atitinkančia, ir ją taip aprašyti būtų teiginys, kurio įgyvendinimas negali paremti: diagramos vis dar artefaktai, o pilnas atitikimo pareiškimas reikalauja audito kiekvienam struktūros tipui, kiekvienam šriftui ir dokumento metaduomenims kaip visumai

Jeigu jūsų reikalavimas yra archyvinis ar atitikimo profilis, o ne prieinamumo tobulinimas, tai kita eksporto konfigūracija ir kitas patikrų rinkinys, aprašytas PDF/A archyvinio eksporto straipsnyje. Abi susijungia, bet jos atsako skirtingiems auditoriams

Vienas praktinis patarimas ataskaitų konvejeriui: audituokite alternatyvųjį tekstą ten, kur darbo knyga generuojama, o ne eksporto metu. Generatorius žino, ką kiekviena diagramos atvaizdas ar įterpta schema reiškia, ir gali įrašyti tikrą aprašymą į AltText; eksporto laiko eiga gali tik pasakyti, kad aprašymo trūksta. HotXLS skaito ir rašo XLS, XLSX, ODS ir CSV savai iš Delphi ir C++Builder be Excel priklausomybės, o jo eksporto konfigūracijos parinktys išvardytos HotXLS Delphi spreadsheet component produkto puslapyje