Vous remettez un classeur terminé à un collègue et lui demandez de le filtrer, pas de le réécrire. Vous protégez donc la feuille. Dans les anciennes versions de HotXLS, ce geste écrivait une seule chose dans le fichier : <sheetProtection sheet="1" objects="1" scenarios="1"/>, codé en dur, à chaque fois. La feuille était verrouillée, le hachage du mot de passe attaché, et l'utilisateur ne pouvait rien faire du tout, pas même le tri et le filtrage que vous vouliez justement laisser ouverts. La boîte de dialogue "Protéger la feuille" d'Excel comporte quinze cases à cocher pour exactement cette raison, et le moteur ne pouvait en exprimer aucune. Cette lacune est ce que le modèle de protection v2.91.0 corrige
HotXLS est un composant tableur VCL natif pour Delphi et C++Builder qui lit et écrit des fichiers XLS et XLSX sans qu'Excel soit installé. Cet article traite de la partie XLSX de la protection des feuilles de calcul : la nouvelle TXLSXSheetProtectionOption énumération AllowOption propriété qui active ou désactive chaque autorisation, ainsi que la seule règle d'encodage OOXML qui piège tout le monde quand on écrit un <sheetProtection> élément à la main
Ce que protège réellement la protection de feuille
D'abord, il faut poser la limite, parce qu'elle détermine jusqu'où vous pouvez faire confiance à tout cela. Dans le format de feuille de calcul OOXML (ECMA-376), la protection de feuille est une politique d'interaction, pas un chiffrement. Elle indique à une application conforme quelles modifications refuser lorsque la feuille est protégée. Les valeurs des cellules sont toujours stockées dans xl/worksheets/sheetN.xml en texte clair ; décompressez le .xlsx et elles sont là, sous vos yeux. Le mot de passe facultatif est stocké sous forme de court hachage hérité, pas comme une clé qui brouille quoi que ce soit. Quiconque renomme le fichier, ouvre la partie et retire la ligne <sheetProtection> lit et modifie tout
La protection répond donc à "empêchez mon collègue d'écraser une formule par inadvertance", pas à "gardez ces données secrètes face à quelqu'un de motivé". Ce sont des problèmes différents, avec des outils différents. Si vous avez besoin de confidentialité, il vous faut le chiffrement au niveau du classeur couvert dans AES-protected XLSX output, qui chiffre réellement le paquet. La protection de feuille et le chiffrement du classeur se combinent proprement, mais seule la seconde est un verrou. Gardez cette distinction claire et le reste de cette page n'est plus que de la plomberie
Les quinze options et la propriété AllowOption
Chaque feuille de calcul porte désormais un ensemble de TXLSXSheetProtectionOption valeurs qui décrivent ce que l'utilisateur peut encore faire lorsque la feuille est protégée. Les membres correspondent un à un aux attributs OOXML et aux cases à cocher de la boîte de dialogue d'Excel :
xlsxSpoEditObjects,xlsxSpoEditScenarios: modifier les objets dessinés et les scénarios hypothétiquesxlsxSpoFormatCells,xlsxSpoFormatColumns,xlsxSpoFormatRows: reformater les cellules, les colonnes, les lignesxlsxSpoInsertColumns,xlsxSpoInsertRows,xlsxSpoInsertHyperlinks: insérer des colonnes, des lignes, des liensxlsxSpoDeleteColumns,xlsxSpoDeleteRows: supprimer des colonnes, des lignesxlsxSpoSelectLockedCells,xlsxSpoSelectUnlockedCells: déplacer la sélection sur des cellules verrouillées ou non verrouilléesxlsxSpoSort,xlsxSpoAutoFilter,xlsxSpoPivotTables: trier des plages, utiliser les listes déroulantes AutoFilter, travailler avec des tableaux croisés dynamiques
Vous lisez et écrivez les bits individuels via la propriété indexée AllowOption propriété sur TXLSXWorksheet. AllowOption[Opt] = True signifie que l'action est autorisée ; le mettre à False l'interdit. L'ensemble entier est aussi accessible d'un seul coup via SheetProtectionOptions, un TXLSXSheetProtectionOptions (un simple Pascal set of), ce qui vous permet de l'enregistrer, de le restaurer ou de le remplacer d'un seul bloc
La valeur par défaut compte et c'est volontaire : une feuille de calcul fraîchement créée commence avec toutes les options autorisées. Le constructeur initialise SheetProtectionOptions avec toute la plage, [Low(TXLSXSheetProtectionOption)..High(TXLSXSheetProtectionOption)]. Vous réduisez ensuite cet ensemble en excluant les actions que vous voulez interdire, plutôt qu'en construisant un jeu d'autorisations à partir de rien. C'est ce choix qui aligne la règle d'encodage du générateur, plus bas, sur le comportement d'Excel
Protéger une feuille tout en laissant le tri et le filtrage ouverts
Voici le cas courant de bout en bout : protégez un rapport terminé pour empêcher toute réorganisation de sa mise en page, mais laissez le lecteur le trier et le filtrer. Notez que Protect et les options sont indépendantes. Protect fait passer la feuille à l'état protégé et stocke le hachage facultatif du mot de passe ; il ne touche pas à l'ensemble d'options. Vous ajustez AllowOption séparément, et les bascules prennent effet une fois la feuille protégée et enregistrée
var
wb: TXLSXWorkbook;
sh: TXLSXWorksheet;
begin
wb := TXLSXWorkbook.Create;
try
sh := wb.Sheets.Add('Protected');
sh.Cells[1, 1].Value := 'Region'; sh.Cells[1, 2].Value := 'Units';
sh.Cells[2, 1].Value := 'North'; sh.Cells[2, 2].Value := 120;
sh.Cells[3, 1].Value := 'South'; sh.Cells[3, 2].Value := 98;
// Protect with a password. This only sets the protected state + hash;
// the option set is left at its all-permitted default.
sh.Protect('HotXLS-2026');
// Narrow: keep sort + AutoFilter, forbid reshaping and reformatting.
sh.AllowOption[xlsxSpoSort] := True;
sh.AllowOption[xlsxSpoAutoFilter] := True;
sh.AllowOption[xlsxSpoFormatCells] := False;
sh.AllowOption[xlsxSpoFormatColumns] := False;
sh.AllowOption[xlsxSpoFormatRows] := False;
sh.AllowOption[xlsxSpoInsertRows] := False;
sh.AllowOption[xlsxSpoDeleteRows] := False;
if wb.SaveAs('protection.xlsx') <> 1 then
Writeln('SaveAs failed');
finally
wb.Free;
end;
end;
Deux points à retenir de cet extrait. Les Sort et AutoFilter lignes sont écrites explicitement même si elles prennent toutes deux par défaut True; c'est une documentation pour le prochain mainteneur, pas une exigence fonctionnelle. Et puisque les valeurs par défaut sont permissives, les seules lignes qui modifient le fichier de sortie sont celles qui définissent une option sur False. Ce n'est pas un hasard de cette API, c'est le format filaire OOXML qui transparaît, et c'est justement le sujet de la section suivante
La règle d'encodage : omission = autorisation, attr=0 = interdiction
C'est l'unique point contre-intuitif de toute cette fonctionnalité, et c'est là que la <sheetProtection> saisie à la main se trompe le plus souvent. Dans OOXML, chaque attribut par action est un forbid indicateur, et son absence vaut autorisation. Un attribut absent signifie que l'action est autorisée. Un attribut écrit sous la forme "0" signifie que l'action est interdite tant que la feuille est protégée. Il n'existe pas de formatCells="1" dans un fichier bien formé pour signifier « le formatage est autorisé » ; il suffit simplement de laisser l'attribut de côté. (La valeur par défaut d'un attribut absent est la valeur booléenne OOXML true, et ces attributs sont nommés de façon que « true » signifie que la modification correspondante est autorisée.)
Le générateur HotXLS reflète cela exactement. Il émet sheet="1" pour activer la protection, puis parcourt l'ensemble d'options et écrit attr="0" uniquement pour les options que vous avez définies sur False. Les actions autorisées n'ajoutent rien à la sortie. Le classeur de la section précédente se sérialise donc à quelque chose comme ceci, en ne transportant que les actions interdites plus le hachage du mot de passe :
// Conceptual output for the snippet above (attributes elided for brevity):
// <sheetProtection sheet="1"
// formatCells="0" formatColumns="0" formatRows="0"
// insertRows="0" deleteRows="0"
// password="...4-hex..."/>
// Note what is NOT there: no sort, no autoFilter, no selectLockedCells.
// Their absence is exactly what tells Excel those actions stay allowed.
Si vous venez de l'ancienne chaîne codée en dur et que vous vous attendiez à voir chaque attribut écrit noir sur blanc, cela paraît clairsemé, presque faux. C'est pourtant correct. Un fichier qui énumérerait sort="1" et autoFilter="1" voudrait dire la même chose pour un lecteur conforme, mais Excel lui-même écrit la forme minimale, limitée aux interdictions, et s'y conformer garde les diffs petits et les allers-retours sans surprise. Les objects et scenarios attributs suivent la même règle : ils sont autorisés par défaut, donc ils n'apparaissent qu'en "0" lorsque vous les interdisez, ce qui est l'inverse de l'ancien objects="1" scenarios="1" qui était émis sans condition
Relire la protection : fidélité des allers-retours
Un modèle d'autorisations que vous pouvez écrire mais pas relire est une voie à sens unique, et le symptôme habituel est un cycle charger-modifier-enregistrer qui élargit silencieusement les autorisations. HotXLS corrige cela. Quand ParseWorksheetXml rencontre un <sheetProtection> élément, il passe la feuille en mode protégé, capture le hachage du mot de passe s'il est présent, puis décode chaque attribut par action en AllowOption en utilisant la même convention à l'envers : un attribut présent et égal à "0" interdit l'action ; un attribut absent laisse l'option à sa valeur autorisée par défaut
var
wb: TXLSXWorkbook;
sh: TXLSXWorksheet;
begin
wb := TXLSXWorkbook.Create;
try
wb.LoadFromFile('protection.xlsx');
sh := wb.Sheets[1]; // XLSX sheets are 1-based
if sh.IsProtected then
begin
Writeln('Protected; password hash present: ',
sh.SheetProtectHash <> '');
Writeln('Sort allowed: ', sh.AllowOption[xlsxSpoSort]);
Writeln('AutoFilter allowed: ', sh.AllowOption[xlsxSpoAutoFilter]);
Writeln('FormatCells allowed:', sh.AllowOption[xlsxSpoFormatCells]);
end;
finally
wb.Free;
end;
end;
Chargez le fichier produit par le générateur et vous obtenez Sort et AutoFilter de retour sous la forme de True, FormatCells sous la forme de False, l'ensemble que vous avez enregistré, intact. Cette symétrie est tout l'intérêt du modèle : modifiez une cellule dans une feuille protégée avec autorisations partielles puis enregistrez à nouveau, et les quatorze autorisations que vous n'avez pas touchées survivent au lieu de retomber sur l'ancien comportement tout ou rien
Notes pratiques et limites
Quelques points à connaître avant d'intégrer cela à une chaîne de génération de rapports :
- Le mot de passe est faible par conception. La protection de feuille XLSX stocke un hachage hérité sur 16 bits (le même qu'Excel utilise depuis des décennies), conservé ici pour l'interopérabilité. Il décourage les modifications accidentelles ; il ne résiste pas à un attaquant. Ne le traitez pas comme un gardien de secret. Pour une vraie protection, chiffrez le classeur
- Définir les options avant de protéger est parfaitement acceptable.
AllowOptionpeut être attribué que la feuille soit actuellement protégée ou non ; les bascules décrivent simplement ce que la protection autorisera une foisProtectentrera en vigueur.UnProtectréinitialise l'état protégé et le hachage, mais conserve votre ensemble d'options pour la prochaine fois - La sémantique des cellules verrouillées s'applique toujours. La protection bloque seulement les modifications apportées aux cellules dont l'attribut
Lockedest défini (la valeur par défaut du classeur). Laisser une zone de saisie modifiable relève du style de cellule, pas d'une option de protection ; les deux couches se combinent de la même façon que dans Excel - C'est le moteur XLSX. Le modèle d'options reflète les anciens
Allow*propriétés du moteur XLS, mais les noms de l'énumération et de la propriété ici (xlsxSpo*,AllowOption) appartiennent àTXLSXWorksheetdanslxHandleX. Si vous pilotez aussi la mise en page d'impression sur les mêmes feuilles, le guide sur la protection et la mise en page explique comment ces paramètres cohabitent avec les zones d'impression et les en-têtes, et validation des données, AutoFilter et les tableaux se combine naturellement avec le fait de laisserxlsxSpoAutoFilterouvert sur un rapport verrouillé
Le modèle de protection granulaire et le reste du moteur de lecture/écriture XLSX sont fournis dans le HotXLS Component pour Delphi et C++Builder ; la page produit contient l'API complète des feuilles de calcul, y compris la référence exhaustive des options de protection