
# Actions sur les fichiers

Les actions de fichier opèrent sur le stockage configuré de l'application, qu'il s'agisse du système de fichiers local ou d'un stockage objet.

## Stockage

| Opérateur  | Propriétés                        | Fait                                  |
| ---------- | --------------------------------- | ------------------------------------- |
| `upload`   | `source`, `path?`, `contentType?` | Téléverse un fichier vers le stockage |
| `download` | `key`                             | Télécharge un fichier stocké          |
| `delete`   | `key`                             | Supprime un fichier stocké            |
| `copy`     | `source`, `destination`           | Copie un fichier stocké               |
| `move`     | `source`, `destination`           | Déplace ou renomme un fichier         |
| `list`     | `prefix`, `limit?`                | Liste les fichiers sous un préfixe    |

## Métadonnées et accès

| Opérateur     | Propriétés                        | Fait                                                    |
| ------------- | --------------------------------- | ------------------------------------------------------- |
| `getMetadata` | `key`                             | Lit la taille, le type de contenu et le reste           |
| `signUrl`     | `key`, `expiresIn?`, `operation?` | Émet une URL à durée limitée, en lecture ou en écriture |

## Génération

| Opérateur      | Propriétés                                                                               | Fait                                 |
| -------------- | ---------------------------------------------------------------------------------------- | ------------------------------------ |
| `generatePdf`  | `template`, `filename`, `data?`, `pageSize?`, `orientation?`, `margins?`, `destination?` | Rend un gabarit HTML en PDF          |
| `generateCsv`  | `data`, `filename`, `columns?`, `delimiter?`, `includeHeaders?`, `destination?`          | Écrit un CSV à partir d'un tableau   |
| `generateXlsx` | `data?` ou `sheets?`, `filename`, `columns?`, `sheetName?`, `destination?`               | Écrit un classeur à partir de lignes |

## Analyse et transformation

| Opérateur        | Propriétés                                                                   | Fait                                        |
| ---------------- | ---------------------------------------------------------------------------- | ------------------------------------------- |
| `parseCsv`       | `source?`, `key?`, `content?`, `columns?`, `skipRows?`, `delimiter?`         | Analyse un CSV en lignes                    |
| `parseXlsx`      | `source?`, `key?`, `sheet?`, `header?`, `range?`, `skipRows?`                | Analyse une feuille en lignes               |
| `extractText`    | `source`, `format?`                                                          | Extrait le texte d'un document              |
| `transformImage` | `source`, `width?`, `height?`, `fit?`, `format?`, `quality?`, `destination?` | Redimensionne ou convertit une image        |
| `compress`       | `files`, `filename`, `destination?`                                          | Compresse plusieurs fichiers en une archive |

Comme toute étape d'automatisation, une action de fichier accepte aussi `name`, `label`, `continueOnError`, `timeout` et `retry` (avec `maxAttempts`, `delayMs` et une `strategy` `fixed` ou `exponential`).

`destination` omis range la sortie dans un stockage temporaire, nettoyé automatiquement après `STORAGE_TEMP_CLEANUP_AFTER` — 24 heures par défaut.

## CSV

`parseCsv` a besoin d'exactement une entrée : `source` (une clé de stockage), `key` (son alias), ou `content` — du texte CSV en ligne, qui analyse un corps de webhook ou la sortie d'une étape précédente sans aller-retour par le stockage. N'en donner aucune est une erreur de configuration.

`skipRows` retire ce nombre de lignes non vides en tête, et rien d'autre : il enlève donc un préambule sans changer la forme de la sortie — la première ligne survivante est toujours lue comme l'en-tête, et les lignes restent indexées par nom d'en-tête.

`delimiter` vaut virgule, point-virgule, tabulation ou barre verticale. Omis, il est détecté automatiquement en comptant les candidats **hors des champs entre guillemets** dans la première ligne survivante : un export délimité par des points-virgules dont l'en-tête contient légitimement une virgule se lit donc toujours correctement. Passez `columns` pour faire la correspondance explicitement, chaque entrée prenant un `name` plus un `header` nommé ou un `index` à base zéro.

## Tableurs — un sous-ensemble fermé

`parseXlsx` et `generateXlsx` prennent en charge un **sous-ensemble nommé et fermé** du format tableur, plutôt que le format dans son ensemble. À la lecture, ce sous-ensemble comprend : les chaînes partagées et en ligne, les nombres, les booléens, les dates reconnues par le format numérique de la cellule — un numéro de série de date Excel est sinon indistinguable d'un nombre ordinaire — et les formules lues comme leur **valeur en cache**, jamais évaluées. Les dates reviennent en chaînes ISO 8601 plutôt qu'en objets date, ce qui leur permet de survivre à un enregistrement dans l'historique d'exécution puis à une relecture par un gabarit.

### Le mur est aux données hors de la grille de cellules

Un classeur portant un graphique, un dessin, une image incorporée, un tableau croisé dynamique ou une macro est **refusé en le nommant**. Le lire rendrait les cellules et écarterait silencieusement la partie du document à laquelle son auteur tenait, ce qui est le pire dénouement disponible : une réponse plausible qui passe à côté de l'intérêt du fichier.

Le refus est détecté à la fois sur les chemins des parties de l'archive et sur ses surcharges de type de contenu, parce que les deux peuvent se contredire. La mise en forme cosmétique — polices, remplissages, bordures — n'est **pas** refusée mais ignorée, puisque la refuser reviendrait à refuser à peu près tout classeur réel. Hors du sous-ensemble, l'action échoue bruyamment et délibérément : convertissez le fichier plutôt que de vous fier à une réponse fausse.

### Lecture

`parseXlsx` prend le classeur en `source` ou en `key`, son alias ; une URI de données et une URL `https` sont également acceptées. `sheet` sélectionne une feuille par son nom, ou par position à base zéro quand on donne un nombre ; omis, c'est la première feuille dans l'ordre déclaré du classeur qui est lue. `range` restreint la lecture à une fenêtre de style A1, par défaut la plage utilisée de la feuille. `header` traite la première ligne comme un en-tête, la promeut en `columns` et l'exclut des données. `skipRows` retire ensuite ce nombre de lignes en haut de la grille.

La sortie porte les lignes, plus le nom de la feuille, tous les noms de feuilles du classeur, le nombre de lignes et les colonnes. Cette liste de noms est ce qui permet à une automatisation de découvrir les feuilles d'un classeur à un premier appel et d'en viser une au second.

```yaml
- name: importSheet
  type: file
  operator: parseXlsx
  props:
    source: '{{trigger.data.key}}'
    sheet: Orders
    header: true
    range: 'A1:F500'
```

### Écriture

`generateXlsx` écrit l'ensemble minimal de parties qu'un consommateur exige, en n'ajoutant une partie de styles que lorsqu'une cellule de date est présente. Passez `data` pour une feuille unique, nommée par `sheetName`, ou `sheets` pour plusieurs, chaque entrée prenant un nom, ses propres données et éventuellement ses propres colonnes. `columns` sélectionne et ordonne les champs et fournit leurs libellés d'en-tête.

Le refus est ici par **valeur de cellule** : tout ce qui sort de chaîne, nombre, booléen et date — un objet, un tableau, un grand entier, un « pas-un-nombre », une date invalide — fait échouer l'étape avec une erreur nommant la feuille et la référence de cellule, plutôt que d'être converti en une chaîne d'apparence plausible.

Faire l'aller-retour d'un classeur généré à travers l'analyseur est sans perte **à l'intérieur** du sous-ensemble, et seulement à l'intérieur.

```yaml
- name: exportOrders
  type: file
  operator: generateXlsx
  props:
    data: '{{fetchOrders.records}}'
    filename: 'orders-{{trigger.data.month}}.xlsx'
    sheetName: Orders
    destination: exports/
```

## PDF et images

```yaml
- name: invoice
  type: file
  operator: generatePdf
  props:
    template: invoice-template
    filename: 'invoice-{{trigger.data.id}}.pdf'
    data: '{{trigger.data}}'
    pageSize: A4
    orientation: portrait
    destination: invoices/
```

```yaml
- name: thumbnail
  type: file
  operator: transformImage
  props:
    source: '{{upload.result.key}}'
    width: 320
    format: webp
    quality: 70
```

Une conversion qui ne nomme aucun format encode en WebP, et un simple redimensionnement conserve le format source plutôt que de le transcoder. C'est le comportement intégré et non un réglage — nommez un format sur l'action quand un consommateur particulier a besoin d'un autre codec.

## Pages connexes

- [Présentation des automatisations](/fr/docs/automations-overview) — les étapes, leurs sorties et le vocabulaire de gabarit.
- [Présentation des buckets](/fr/docs/buckets-overview) — le stockage sur lequel ces opérateurs travaillent.
- [URL signées](/fr/docs/signed-urls) — ce que `signUrl` émet, et pour combien de temps.
