Skip to content
Power Platform - Apps - Automate - SharePoint
  • Pages
    • Support Power Platform - Power Apps - Power Automate
      • Licences
      • Mises à jour (waves)
      • Environnement & Solutions
        • Attribuer des droits sur un environnement
      • Power BI
      • Liens vers nos supports
    • Architecture Power Platform
      • Modéliser des données
    • Administrer Power Platform
      • Références
      • Sécurité
      • Center of Excellent (CeE)
      • Application Lifecycle Management (ALM) [WiP]
    • Power Apps
      • Références
      • Différence entre le développement impératif et le développement déclaratif
      • Les types d’objets dans Power Apps Canvas
      • Process de développement d'applications PowerApps
        • Contrôles
        • Contrôles modernes
        • Charte de nommage et bonnes pratiques Power Apps Canvas
      • Power Apps - Fonctions principales
        • Tips Fonctions
        • Fonction Patch
          • Patch des types complexes d'une liste SharePoint
        • ForAll, GroupBy et AddColumns dans Power Apps Canvas
        • Les formules nommées (Formulas) dans Power Apps Canvas
      • Modes opératoires
        • Application Canvas - Guide de survie (Liste SP pour mobile)
          • Création d’une application Power Apps Canvas mobile et Excel [WiP]
          • Création d’une application Power Apps Canvas
        • Flux PowerAutomate à partir de Power Apps
        • Compléter un modèle Word et générer un PDF [Premium]
        • Récupérer une photo depuis la caméra
        • Listes en cascade
        • Sélectionner un utilisateur (Liste SP)
        • Partager une application Power Apps
        • Création d’un composant MsgBox de confirmation de suppression
      • AI Builder dans Power Apps
      • Gestion du cycle de vie d’une application Power Apps (ALM)
      • Alternatives à PowerApps
      • Applications basées sur un modèle (model driven apps)
        • Modèles Word avec une application pilotée par modèle
        • Lancer un flux depuis un bouton d'une application pilotée par modèle
        • Ressources JavaScript
      • Développeur
        • JS
        • Outils externes
        • Bibliothèque de composants
        • [Dev] Création d’une liste SharePoint depuis Node.js
          • [Dev] Import d’un fichier Excel dans une liste SharePoint
      • Quizz
    • Power Automate
      • Références
      • Syntaxe générale
      • Fonctions
        • JSON
        • Tips
        • Manipulations fichiers SharePoints [ToDo]
      • Modes opératoires
        • Approbations
          • Généralités
          • Approbations simples
          • [Exo] Commande fournisseur
        • [WiP] Ajouter un bouton de colonne SharePoint qui exécute un flux
        • Créer un PDF à partir de code HTML avec image
        • [WiP] Exécuter un flux depuis une ligne sélectionnée dans Excel
          • Copier un fichier depuis une PJ Outlook
        • Envoyer "en tant que"
        • Compter des éléments, même supprimés (table Audits)
      • AI Builder dans Power Automate
      • Alternatives à Power Automate
      • Power Automate pour le Bureau (PA
        • Ressources pédagogiques
    • Dataverse
      • Références
      • Common Data Model
      • Tables [WIP]
      • Colonnes [WIP]
      • Sécurité
      • Développeur
      • Référence automatique
      • Application pilotée par modèle
        • Exemple pratique
        • Migration depuis Access
    • copilot
      Copilot
      • copilot-studio
        Copilot Studio
      • copilot
        [Exo] Copilot
        • Copilot pour Power Apps (Office Agent)
        • [Exo1] Créer une application Canvas
        • [Exo2] Créer une application Canevas Power Apps pour une solution immobilière à l’aide de Copilot dans Power Apps
        • [Exo3] Générer du texte avec GPT dans AI Builder
        • [Exo4] Créer un site Web Power Pages avec Copilot
        • [Exo5] Créer un copilote pour une solution immobilière à l’aide du langage naturel dans Copilot Studio
        • [Exeo6@ Prédiction avec AI Builder
      • power-automate
        Copilot pour Power Automate
      • power-apps
        Copilot pour Power Apps
    • Microsoft 365 & SharePoint
      • Vue d'ensemble de Microsoft 365 et SharePoint
      • Déroulé pédagogique
        • Module 1 : Microsoft 365 et SharePoint Online
        • Module 2 : Bibliothèques et listes
        • Module 3 : Intégration Office et gestion des documents
        • Module 4 : Type de contenu
        • Module 5 : Personnalisation des pages
        • Module 6 : Personnalisation des sites et des espaces de travail
        • Module 7 : Gestion de la sécurité
        • Module 8 : Workflows Power Automate
      • Bonnes pratiques
      • Sites SharePoint
        • Types de sites
        • Hiérarchies de sites
          • Sous-sites vs Hubs de sites
        • Créer un site
        • Principaux composants
          • Navigation
          • Composant WebPart dans les pages
          • Bibliothèques de document & Listes
          • Lien avec Teams
        • Pages d'un site SharePoint
        • Partage de flux d'un fichier ou d'un élément sélectionné
      • Listes SharePoint
        • Créer une liste
          • Créer une colonne
          • Gérer les vues
        • Power Automate avec des listes SharePoint
        • Mettre à jour une Liste SharePoint depuis Excel
        • TIPS
      • Bibliothèques de fichiers & dossiers SharePoint [WiP]
        • Rétention
        • Généralités
          • Création d'un nouveau document
          • Associer un modèle de document
          • Affichage et modification de documents dans le navigateur
          • Affichage et modification de documents dans le client
          • Téléchargement de documents
          • Déplacement et copie de documents
          • Affichage et modification des paramètres de la bibliothèque de documents
          • Paramètres de gestion des versions, approbation du contenu et extraction de documents
      • Intégration Power Apps
      • Droits & sécurité
      • API
      • Administration & rôles
    • Exercices
      • pl-7001
        PL-7001 - Power Apps Canvas
        • Lab 0 – Valider l'environnement de laboratoire
        • Lab 1 – Créer une application canevas à partir de données
        • Lab 2 – Modèle de données
        • Lab 3 – Créer une application canevas
        • Lab 4 – Créer l'interface utilisateur
        • Lab 5 – Données externes
        • Lab 6 – Formulaires
        • Lab 7 – Gérer les applications canevas
    • Exos Power Apps Power Automate
      • [Exo A] Flux avec une liste SharePoint
      • [Exo06] Créer une application Canvas avec Copilot
      • Flux avec une table Dataverse
        • Créer la source Dataverse
        • Créer le flux de bouton
        • Créer un flux automatisé avec filtre
      • Flux avec une liste SharePoint

[Dev] Import d’un fichier Excel dans une liste SharePoint

Stack : Node.js + PnPjs v4 + xlsx + certificat Azure AD

Prérequis

Projet SPFx existant avec PnPjs v4 configuré
Certificat Azure AD en place (private.key, thumbprint)
Liste SharePoint cible déjà créée avec les colonnes correspondantes
Fichier .env complété (voir guide de création de liste)

Phase 1 — Préparer le fichier Excel

Étape 1 — Respecter la structure attendue

La première ligne du fichier Excel doit contenir les noms exacts des colonnes de la liste SharePoint cible.
Règle
Détail
Nom de colonne
Identique au nom interne SharePoint (sensible à la casse)
Dates
Format YYYY-MM-DD (ex. 2026-03-30)
Nombres
Valeurs numériques sans unité ni espace
Colonnes vides
Laisser la cellule vide — ne pas mettre N/A ou -
Colonne choix
La valeur doit correspondre exactement à l’un des choix définis
There are no rows in this table

Étape 2 — Placer le fichier dans le projet

mon-projet/
└── sessions.xlsx ← à la racine du projet

Phase 2 — Installer la dépendance

Étape 3 — Installer la bibliothèque de lecture Excel

npm install xlsx

Phase 3 — Créer le script d’import

Étape 4 — Créer scripts/importList.ts

import "dotenv/config";
import { spfi } from "@pnp/sp";
import { SPDefault } from "@pnp/nodejs";
import * as fs from "fs";
import * as path from "path";
import * as XLSX from "xlsx";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";

// ─── Configuration ─────────────────────────────────────────────────
const TENANT_ID = process.env.TENANT_ID!;
const CLIENT_ID = process.env.CLIENT_ID!;
const THUMBPRINT = process.env.THUMBPRINT!;
const KEY_PATH = process.env.KEY_PATH!;
const SITE_URL = process.env.SITE_URL!;
const SP_ROOT_URL = process.env.SP_ROOT_URL!;

const LIST_NAME = "NomDeLaListe"; // ← à adapter
const EXCEL_PATH = path.resolve(__dirname, "../fichier.xlsx"); // ← à adapter
// ──────────────────────────────────────────────────────────────────

async function importData(): Promise<void> {

// Lecture du fichier Excel
const workbook = XLSX.readFile(EXCEL_PATH);
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const rows: Record<string, any>[] = XLSX.utils.sheet_to_json(sheet);

console.log(`${rows.length} ligne(s) trouvée(s).`);

// Connexion SharePoint
const privateKey = fs.readFileSync(KEY_PATH, "utf-8").trim();

const sp = spfi(SITE_URL).using(
SPDefault({
baseUrl: SITE_URL,
msal: {
config: {
auth: {
clientId: CLIENT_ID,
authority: `https://login.microsoftonline.com/${TENANT_ID}`,
clientCertificate: {
thumbprint: THUMBPRINT,
privateKey: privateKey
}
}
},
scopes: [`${SP_ROOT_URL}/.default`]
}
})
);

const list = sp.web.lists.getByTitle(LIST_NAME);

// Import ligne par ligne
for (const [index, row] of rows.entries()) {
try {

// Construire l'objet à envoyer — adapter les champs selon la liste
// ?? "" : envoyer une chaîne vide si la cellule est vide (colonnes texte)
// ?? null : envoyer null si la cellule est vide (colonnes date)
// Number() : convertir en nombre (colonnes numériques)

// Conversion de date JJ/MM/AAAA → AAAA-MM-JJ (format attendu par SharePoint)
// Exemple : "30/03/2026" → "2026-03-30"
const toIsoDate = (val: string | undefined): string | null => {
if (!val) return null;
const parts = val.split("/");
if (parts.length !== 3) return val; // déjà au bon format ou valeur inattendue
return `${parts[2]}-${parts[1]}-${parts[0]}`;
};

const item = {
Title: row["Title"] ?? "", // texte → chaîne vide par défaut
CodeFormation: row["CodeFormation"] ?? "", // texte → chaîne vide par défaut
DateSession: toIsoDate(row["DateSession"]), // JJ/MM/AAAA → AAAA-MM-JJ
NbConfirmes: Number(row["NbConfirmes"]) || 0, // nombre → 0 si vide ou NaN
NbOption: Number(row["NbOption"]) || 0, // nombre → 0 si vide ou NaN
// ↑ Ajouter ici tous les autres champs de la liste en suivant le même modèle
};

await list.items.add(item);
console.log(` [${index + 1}/${rows.length}] Importé : ${row["Title"] ?? row[Object.keys(row)[0]]}`);

} catch (err: any) {
console.error(` [${index + 1}] Erreur : ${err.message}`);
}
}

console.log("Import terminé.");
}

importData()
.then(() => process.exit(0))
.catch((err) => {
console.error("Erreur fatale :", err.message ?? err);
process.exit(1);
});

Étape 5 — Adapter les types de colonnes

Dans la boucle d’import, identifier les colonnes nécessitant une conversion :
Type SharePoint
Traitement dans le script
Ligne de texte
String(val) ou val ?? ""
Nombre
Number(val) || 0
Date
Laisser en string YYYY-MM-DD — SharePoint accepte ce format
Choix
La valeur doit correspondre exactement à un choix existant
Oui/Non
Boolean(val) ou val === "Oui"
Personne
Requiert le loginName ou l’id utilisateur — ne pas passer en import direct
There are no rows in this table
Exemple concret de mapping avec les 3 types les plus courants
Lors de la construction de l’objet item à envoyer à SharePoint, chaque champ suit une logique différente selon son type :
// Colonne texte — si la cellule est vide, envoyer une chaîne vide plutôt que undefined
Title: row["Title"] ?? "",

// Colonne texte — même logique, le nom de la clé doit correspondre exactement
// au nom interne de la colonne SharePoint
CodeFormation: row["CodeFormation"] ?? "",

// Colonne date — si la cellule est vide, envoyer null plutôt qu'une chaîne vide
// (SharePoint rejetterait "" pour un champ de type date)
DateSession: row["DateSession"] ?? null,
L’opérateur ?? (nullish coalescing) renvoie la valeur de droite uniquement si la valeur de gauche est null ou undefined — il n’écrase pas 0 ou false, contrairement à ||.

Phase 4 — Configurer et lancer

Étape 6 — Ajouter le script dans package.json

"scripts": {
"import-list": "ts-node --project tsconfig.scripts.json scripts/importList.ts"
}

Étape 7 — Vérifier la structure du projet

mon-projet/
├── fichier.xlsx ← fichier Excel source
├── scripts/
│ └── importList.ts ← script d'import
├── .env ← variables d'environnement
├── tsconfig.scripts.json
└── package.json

Étape 8 — Lancer l’import

npm run import-list
Résultat attendu :
N ligne(s) trouvée(s).
[1/N] Importé : ...
[2/N] Importé : ...
...
Import terminé.

Gestion des erreurs courantes

Erreur
Cause probable
Correction
401 Unauthorized
Certificat ou permissions incorrects
Vérifier Azure AD et le thumbprint
Unsupported app only token
Permission SharePoint de type Application manquante
Ajouter Sites.FullControl.All Application dans Azure AD
The field X does not exist
Nom de colonne Excel différent du nom interne SP
Vérifier la casse et le nom exact de la colonne
Invalid choice value
Valeur non définie dans la colonne Choix
Vérifier les valeurs autorisées dans la liste SP
Cannot convert to number
Cellule vide dans une colonne numérique
Ajouter `
There are no rows in this table

Bonnes pratiques

Tester l’import avec une seule ligne avant de lancer les données complètes
Conserver le fichier Excel source dans Git (sans données sensibles)
Ne jamais commiter .env, private.key et appcert.pfx
En cas d’import partiel (erreur à mi-chemin), supprimer les éléments déjà créés avant de relancer pour éviter les doublons
Pour les gros volumes (> 100 lignes), envisager un import par batch avec Promise.all() par groupes de 10
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.