Article technique

Exporter des feuilles Excel en PDF sous Delphi sans Office

Pour exporter une feuille Excel en PDF depuis Delphi ou C++Builder sans qu'Office soit installé, appelez SaveAsPDF sur une feuille ou un classeur HotXLS. HotXLS est un composant Excel VCL natif, et son export de feuille vers PDF restitue la plage utilisée de la feuille dans un fichier PDF 1.4 autonome, en reportant les largeurs de colonnes Excel et le texte affiché des cellules sur des pages A4 avec une pagination multipage automatique. Aucune copie d'Excel, aucun pilote d'imprimante et aucune DLL externe ne participe au rendu

HotXLS traite le PDF comme un format de présentation des données, un frère de ses chemins d'export CSV, TSV et HTML plutôt que comme un moteur de rendu fidèle au pixel. L'export reproduit le contenu tabulaire et la mise en page : les valeurs que vous voyez dans la grille, les proportions des colonnes et le quadrillage autour des cellules. Ce cadrage compte parce qu'il pose d'emblée une attente honnête, et le reste de cet article porte précisément sur l'endroit où passe la limite

Comment convertir Excel en PDF sous Delphi sans Office ?

Le chemin le plus court tient en un seul appel. TXLSWorksheet expose SaveAsPDF(FileName) et SaveAsPDF(Stream), et TXLSWorkbook expose les deux mêmes surcharges, qui délèguent à la feuille active. Chacune renvoie un Integer, 1 en cas de succès et -1 en cas d'échec, si bien que vous pouvez brancher sur le résultat sans envelopper l'appel dans votre propre gestion d'exceptions

uses
  lxHandle;

var
  Book: TXLSWorkbook;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('sales-june.xlsx');
    // Restitue la plage utilisée de la feuille active directement dans report.pdf.
    if Book.SaveAsPDF('report.pdf') = 1 then
      Writeln('PDF written');
  finally
    Book.Free;
  end;
end;

Quand vous appelez SaveAsPDF sur une feuille de calcul, HotXLS exporte le UsedRange de cette feuille, le rectangle englobant de toutes les cellules renseignées. La surcharge au niveau du classeur est une commodité qui délègue à la feuille active : un rapport multifeuille boucle donc sur les feuilles dont il a besoin, ou sélectionne la feuille active avant l'appel. Il n'existe pas de mode classeur entier en une seule passe qui concaténerait tous les onglets : chaque appel restitue une feuille ou une plage

Comment HotXLS transforme-t-il une plage utilisée en pages PDF ?

HotXLS parcourt la plage utilisée cellule par cellule et la dispose en une grille paginée. La géométrie des colonnes vient directement d'Excel : chaque largeur de colonne est convertie de l'unité de largeur Excel en points typographiques, avec un plancher minimal pour qu'aucune colonne ne se réduise à un filet. Quand les colonnes réunies dépassent la largeur utile de la page, HotXLS les réduit uniformément pour les faire tenir ; quand elles tiennent déjà, il les laisse à leur largeur naturelle plutôt que de les étirer sur toute la feuille

Les lignes s'écoulent ensuite vers le bas de la page jusqu'à ce que la suivante franchisse la marge inférieure, moment où HotXLS ouvre une nouvelle page et poursuit : une feuille de mille lignes se pagine donc toute seule, sans aucune comptabilité de sauts de page de votre part. Chaque cellule imprime son FormattedText, la chaîne d'affichage produite après application du format numérique, si bien qu'une date apparaît comme la feuille l'affiche et qu'une cellule monétaire conserve ses séparateurs de milliers et son symbole. Le texte qui déborde de sa colonne est rogné à la largeur de la cellule au lieu de se répandre sur la voisine

Schéma HotXLS pour Delphi montrant SaveAsPDF qui pagine la plage utilisée d'une feuille sur plusieurs pages PDF A4
SaveAsPDF restitue la plage utilisée avec la géométrie des colonnes Excel et une pagination automatique — les lignes passent à une nouvelle page dès que la ligne suivante franchirait la marge inférieure

Contrôler l'orientation, les marges et la taille de police

Pour tout ce qui dépasse la mise en page par défaut, pilotez directement l'exportateur. TXLSPDFExport est la classe derrière les aides en une ligne, et elle publie trois propriétés : Orientation (xlsPdfPortrait ou xlsPdfLandscape, portrait par défaut), Margin (en points, 40 par défaut) et FontSize (en points, 9 par défaut). Définissez-les avant d'appeler SaveAsPDF et tout le document les reprend

uses
  lxHandle, lxPDF;

var
  Book: TXLSWorkbook;
  Exporter: TXLSPDFExport;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('wide-ledger.xlsx');
    Exporter := TXLSPDFExport.Create;
    try
      Exporter.Orientation := xlsPdfLandscape;  // fait tenir les feuilles larges sur la page
      Exporter.Margin := 28;                     // marge de page plus serrée, en points
      Exporter.FontSize := 8;                    // lignes plus denses
      Exporter.SaveAsPDF(Book.ActiveSheet, 'ledger.pdf');
    finally
      Exporter.Free;
    end;
  finally
    Book.Free;
  end;
end;

TXLSPDFExport accepte aussi une plage au lieu d'une feuille entière via SaveAsPDF(Range: IXLSRange; ...), ce qui permet d'exporter un bloc de synthèse depuis une feuille qui contient aussi des calculs intermédiaires. Cette surcharge de plage est celle sur laquelle s'appuie en interne l'aide au niveau de la feuille, si bien que la mise en page, la mise à l'échelle et la pagination se comportent de façon identique que vous lui passiez une plage utilisée complète ou une sélection choisie à la main

var
  Book: TXLSWorkbook;
  Exporter: TXLSPDFExport;
  Summary: IXLSRange;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('quarter.xlsx');
    // Exporte seulement le bloc de synthèse, pas les colonnes de calcul à côté.
    Summary := Book.Sheets[1].Range['A1', 'F20'];
    Exporter := TXLSPDFExport.Create;
    try
      Exporter.SaveAsPDF(Summary, 'summary.pdf');
    finally
      Exporter.Free;
    end;
  finally
    Book.Free;
  end;
end;

Pourquoi HotXLS n'incorpore aucune police : le compromis Helvetica et WinAnsi

HotXLS écrit le texte avec la police Helvetica intégrée au PDF et l'encodage WinAnsiEncoding, un choix délibéré de zéro dépendance qui comporte une vraie limite. Parce que Helvetica fait partie des 14 polices standard que tout lecteur PDF conforme embarque déjà, l'exportateur n'incorpore aucun programme de police : le fichier reste petit et s'ouvre partout, sans rien à licencier ni à livrer à côté. Le prix de ce choix est le répertoire de caractères que la page peut afficher

WinAnsiEncoding couvre le jeu Windows-1252 : le texte latin, la ponctuation courante et les accents ouest-européens habituels sont donc rendus correctement, et HotXLS replie une poignée de caractères typographiques, guillemets courbes, tirets demi-cadratin et cadratin et signe euro, dans leurs emplacements CP1252. Les caractères hors de cette plage, idéogrammes CJK, cyrillique, grec et arabe, se réduisent à un point d'interrogation sur la page. Si vos feuilles portent du texte non latin, cet exportateur est le mauvais outil, et un moteur de rendu PDF avec styles complets est le travail qui convient

Graphique HotXLS pour Delphi du répertoire de caractères WinAnsi utilisé par l'export PDF en Helvetica intégrée
L'export PDF n'incorpore aucune police et écrit en Helvetica intégrée avec WinAnsiEncoding — les caractères hors de Windows-1252 se réduisent à un point d'interrogation sur la page

Où s'arrête l'export de feuille vers PDF

HotXLS restitue le contenu et la structure, pas le style visuel complet de la feuille. Les remplissages de cellules, les styles de bordure par arête, les polices et couleurs par cellule, les graphiques et les images incorporées sortent de ce que l'exportateur dessine ; ce que vous obtenez, c'est la grille de texte avec un quadrillage uniforme. C'est le même contrat que respectent les exportateurs HTML et RTF, et c'est le bon pour un rapport ou une remise de données où les chiffres portent le sens et pas le thème

Quand le but est un document stylé et conforme à la charte, le schéma habituel consiste à assembler d'abord les chiffres dans un modèle de feuille de calcul, ce que le flux de génération de rapports piloté par modèle couvre en détail. Et comme rien de tout cela ne touche à COM ni à une instance Excel en cours d'exécution, la chaîne s'inscrit dans le même modèle d'automatisation sans Office que HotXLS utilise partout : du Pascal pur, déployable sur un serveur sans interface, sans interop à licencier ni à surveiller

Le PDF autonome, octet par octet

HotXLS construit la structure du fichier PDF à la main et calcule sa table de références croisées à partir de décalages d'octets exacts, ce qui explique que la sortie s'ouvre dans tous les lecteurs. À mesure qu'il sérialise chaque objet, HotXLS enregistre le décalage de départ de cet objet avant d'ajouter ses octets, puis avance la position courante de la longueur qu'il vient d'écrire, si bien que la table xref tombe précisément sur chaque objet et que startxref marque le début de cette table. Un lecteur qui trouve ces décalages faux ne serait-ce que d'un octet rejette le fichier entier, ce qui fait du décalage calculé en interne le contrat porteur de l'exportateur

Ce contrat entraîne une conséquence stricte qu'il vaut la peine de connaître. Le nœud Pages est écrit en premier comme objet 1, mais sa liste de pages enfants n'est connue qu'une fois toutes les pages émises : HotXLS le réserve donc comme espace réservé et y insère les enfants et le compte définitifs avant la passe de décalages, jamais après. Une fois les octets d'un objet mesurés pour la table xref, ils sont figés : changer un seul octet ensuite décalerait toutes les positions suivantes et corromprait la table. C'est une petite discipline qui achète un PDF 1.4 conforme à la norme sans aucune bibliothèque en dessous

Schéma HotXLS pour Delphi des décalages d'octets calculés en interne qui alimentent la table xref du PDF pendant la sérialisation de SaveAsPDF
HotXLS enregistre le décalage de chaque objet avant d'ajouter ses octets — tout ce qui est mesuré pour la table xref est figé afin que la table reste exacte

Les méthodes SaveAsPDF et la classe TXLSPDFExport présentées ici sont livrées avec le composant Excel HotXLS pour Delphi, aux côtés des exportateurs CSV, HTML et RTF et de l'API complète des feuilles de calcul pour Delphi et C++Builder