Ouvrir un CSV ou XLS directement dans Google Sheets depuis son Mac

Si tu travailles avec Google Sheets au quotidien, tu connais sûrement ce moment pénible : tu reçois un fichier .csv ou .xlsx, et tu dois soit passer par Fichier → Importer dans Sheets, soit glisser le fichier sur Drive, attendre la sync, puis l’ouvrir. Deux ou trois clics de trop, des dizaines de fois par semaine.

Cet article explique comment créer une mini-application macOS qui règle le problème en un clic droit : Ouvrir avec → CSV to Sheets, et c’est parti — le fichier s’uploade automatiquement sur Google Drive et s’ouvre dans Google Sheets.


Le problème en détail

Par défaut sur Mac, les fichiers .csv et .xlsx s’ouvrent dans l’app par défaut (souvent Numbers, LibreOffice ou Excel). Google Sheets n’est pas une app native macOS, donc elle n’apparaît jamais dans la liste “Ouvrir avec”.

Les contournements habituels :

  • Glisser le fichier dans drive.google.com → attendre l’upload → double-cliquer → “Ouvrir avec Google Sheets”
  • Ouvrir Sheets → Fichier → Importer → chercher le fichier
  • Utiliser Google Drive for Desktop (voir alternatives en fin d’article)

Aucune de ces options n’est vraiment fluide. La solution qu’on va construire réduit tout ça à un seul geste.


Ce qu’on va construire

Une application macOS légère (CSV to Sheets.app) qui :

  1. Reçoit un ou plusieurs fichiers CSV, XLS ou XLSX via “Ouvrir avec”
  2. Les uploade sur Google Drive via l’API
  3. Les convertit automatiquement en Google Sheets
  4. Ouvre le fichier dans le navigateur

L’app sera visible dans le menu “Ouvrir avec” du Finder pour tous les fichiers tableur.


Prérequis

  • macOS 12 ou supérieur
  • Google Chrome ou tout navigateur connecté à Google
  • Un compte Google (personnel ou Workspace)
  • Accès au Terminal (Applications → Utilitaires → Terminal)

Étape 1 — Installer Homebrew et Python

macOS inclut un Python système qu’il vaut mieux ne pas toucher. On va installer une version récente via Homebrew, le gestionnaire de paquets standard pour Mac.

Installer Homebrew :

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Si Homebrew est déjà installé, cette commande le met à jour.

Installer Python 3 :

brew install python

Vérifie l’installation :

python3 --version
# Python 3.12.x

Étape 2 — Configurer les credentials Google API

Pour uploader des fichiers sur Google Drive par programme, il faut une clé API OAuth 2.0. C’est une opération unique, qui prend environ 5 minutes.

2.1 Créer un projet Google Cloud

  1. Rends-toi sur console.cloud.google.com
  2. En haut à gauche, clique sur le sélecteur de projet → Nouveau projet
  3. Donne-lui un nom (ex : CSV to Sheets) → Créer

2.2 Activer l’API Google Drive

  1. Dans le menu gauche → APIs et services → Bibliothèque
  2. Cherche Google Drive API → clique dessus → Activer

2.3 Créer les identifiants OAuth

  1. Menu gauche → Identifiants+ Créer des identifiantsID client OAuth
  2. Si demandé, configure l’écran de consentement :
    • Type : ExterneCréer
    • Nom de l’app : CSV to Sheets
    • Sauvegarde (le reste est optionnel)
  3. Retour sur Identifiants → + Créer des identifiantsID client OAuth
  4. Type d’application : Application de bureauCréer
  5. Clique Télécharger JSON

2.4 Placer le fichier credentials

Dans Terminal :

mkdir -p ~/.config/csv_to_sheets
mv ~/Downloads/client_secret_*.json ~/.config/csv_to_sheets/credentials.json

Étape 3 — Installer le script Python

Ce script gère l’authentification Google, l’upload du fichier et l’ouverture de l’URL Sheets.

mkdir -p ~/.config/csv_to_sheets

Crée le fichier ~/.config/csv_to_sheets/csv_to_sheets.py avec le contenu suivant :

#!/usr/bin/env python3
"""
Uploade un fichier tableur sur Google Drive et l'ouvre dans Google Sheets.
Formats supportés : CSV, XLS, XLSX, TSV, ODS
"""

import sys, os, subprocess
from pathlib import Path

def ensure_packages():
    packages = {
        "google.auth": "google-auth",
        "google_auth_oauthlib": "google-auth-oauthlib",
        "googleapiclient": "google-api-python-client",
    }
    for module, package in packages.items():
        try:
            __import__(module)
        except ImportError:
            subprocess.check_call(
                [sys.executable, "-m", "pip", "install", package,
                 "--break-system-packages", "-q"],
                stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
            )

ensure_packages()

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload

SCOPES     = ["https://www.googleapis.com/auth/drive.file"]
CONFIG_DIR = Path.home() / ".config" / "csv_to_sheets"
TOKEN_FILE = CONFIG_DIR / "token.json"
CREDS_FILE = CONFIG_DIR / "credentials.json"

MIMETYPES = {
    ".csv":  "text/csv",
    ".xls":  "application/vnd.ms-excel",
    ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    ".tsv":  "text/tab-separated-values",
    ".ods":  "application/vnd.oasis.opendocument.spreadsheet",
}

def alert(msg):
    subprocess.run(["osascript", "-e",
        f'display dialog "{msg}" buttons {{"OK"}} default button "OK" with icon caution'],
        check=False)

def get_credentials():
    CONFIG_DIR.mkdir(parents=True, exist_ok=True)
    creds = None
    if TOKEN_FILE.exists():
        creds = Credentials.from_authorized_user_file(str(TOKEN_FILE), SCOPES)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            if not CREDS_FILE.exists():
                alert("Fichier credentials manquant.\\nVoir README.")
                sys.exit(1)
            flow = InstalledAppFlow.from_client_secrets_file(str(CREDS_FILE), SCOPES)
            creds = flow.run_local_server(port=0)
        with open(TOKEN_FILE, "w") as f:
            f.write(creds.to_json())
    return creds

def upload_and_open(file_path):
    if not os.path.exists(file_path):
        alert(f"Fichier introuvable :\\n{file_path}")
        sys.exit(1)
    ext      = Path(file_path).suffix.lower()
    mimetype = MIMETYPES.get(ext, "text/csv")
    creds    = get_credentials()
    service  = build("drive", "v3", credentials=creds)
    media    = MediaFileUpload(file_path, mimetype=mimetype, resumable=False)
    result   = service.files().create(
        body={"name": Path(file_path).stem,
              "mimeType": "application/vnd.google-apps.spreadsheet"},
        media_body=media, fields="id"
    ).execute()
    url = f"https://docs.google.com/spreadsheets/d/{result['id']}/edit"
    subprocess.run(["open", url], check=True)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        alert("Usage : csv_to_sheets.py <fichier>")
        sys.exit(1)
    upload_and_open(sys.argv[1])

Installe les dépendances :

python3 -m pip install google-auth google-auth-oauthlib google-api-python-client --break-system-packages -q

Étape 4 — Créer l’application macOS

On crée une app AppleScript qui gère la réception des fichiers via “Ouvrir avec” et les passe au script Python.

PYTHON=$(brew --prefix python)/bin/python3
SCRIPT="$HOME/.config/csv_to_sheets/csv_to_sheets.py"
APP="$HOME/Applications/CSV to Sheets.app"

rm -rf "$APP"

cat > /tmp/csv_to_sheets.applescript << APPLESCRIPT
on open theFiles
    repeat with aFile in theFiles
        set filePath to POSIX path of aFile
        do shell script "xattr -d com.apple.quarantine " & quoted form of filePath & " 2>/dev/null || true; $PYTHON \\"$SCRIPT\\" " & quoted form of filePath
    end repeat
end open

on run
    display dialog "Glissez un fichier CSV ou Excel sur cette app pour l'ouvrir dans Google Sheets." buttons {"OK"} default button "OK"
end run
APPLESCRIPT

osacompile -o "$APP" /tmp/csv_to_sheets.applescript

python3 -c "
import plistlib, pathlib, os
p = pathlib.Path(os.path.expanduser('~/Applications/CSV to Sheets.app/Contents/Info.plist'))
with open(p, 'rb') as f:
    data = plistlib.load(f)
data['CFBundleDocumentTypes'] = [
    {'CFBundleTypeName': 'CSV File', 'CFBundleTypeRole': 'Viewer', 'LSHandlerRank': 'Alternate',
     'LSItemContentTypes': ['public.comma-separated-values-text'],
     'CFBundleTypeExtensions': ['csv', 'tsv']},
    {'CFBundleTypeName': 'Excel File', 'CFBundleTypeRole': 'Viewer', 'LSHandlerRank': 'Alternate',
     'LSItemContentTypes': ['org.openxmlformats.spreadsheetml.sheet', 'com.microsoft.excel.xls'],
     'CFBundleTypeExtensions': ['xlsx', 'xls', 'xlsm']},
]
data['LSUIElement'] = True
with open(p, 'wb') as f:
    plistlib.dump(data, f)
"

/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "$APP"
echo "✅ App créée."

Première utilisation

La première fois que tu lances l’app, macOS affiche un avertissement “développeur non identifié”. Pour le contourner :

  1. Va dans Réglages Système → Confidentialité et sécurité
  2. Tu verras un message mentionnant “CSV to Sheets” → clique Ouvrir quand même

C’est une opération unique. Ensuite, l’app fonctionne sans friction.

Également, au premier upload, ton navigateur s’ouvrira pour te connecter à ton compte Google et autoriser l’accès à Drive. Le token est ensuite sauvegardé localement (~/.config/csv_to_sheets/token.json) — pas besoin de te reconnecter.


Utilisation au quotidien

Clic droit sur n’importe quel fichier .csv, .xls ou .xlsxOuvrir avec → CSV to Sheets.

Le fichier s’uploade sur Google Drive et s’ouvre directement dans Google Sheets dans ton navigateur.

Astuce : Pour en faire l’app par défaut pour tous tes CSV, fais clic droit sur un fichier CSV → Lire les informations → section Ouvrir avec → sélectionne CSV to Sheets → clique Tout modifier.


Pourquoi une App Bundle et pas une Quick Action Automator ?

La solution naturelle sur macOS serait une Quick Action (Action rapide) dans le menu contextuel Finder. Nous l’avons d’abord construite de cette façon, mais les versions récentes de macOS (Ventura, Sonoma, Sequoia) bloquent les Quick Actions non signées lorsqu’elles traitent des fichiers téléchargés depuis internet — affichant une erreur Gatekeeper impossible à contourner sans passer par Apple Developer Program.

La solution App Bundle contourne ce problème : une app créée localement sur ta machine n’a pas d’attribut de quarantaine, et macOS traite l’ouverture de fichiers via “Ouvrir avec” différemment des Quick Actions.


Alternatives

Google Drive for Desktop

La solution la plus simple si tu n’as pas d’objection à installer l’app Google Drive sur ton Mac. Une fois installée, elle crée un dossier Google Drive dans ton Finder. Les fichiers que tu y places se synchronisent automatiquement et peuvent s’ouvrir directement dans Sheets via double-clic.

Avantages : aucune configuration technique, zéro code.
Inconvénients : l’app Google Drive est assez lourde, consomme des ressources en arrière-plan, et nécessite que les fichiers soient dans ton dossier Drive.

Raycast ou Alfred

Ces outils de productivité Mac permettent de créer des workflows personnalisés. On peut créer une action “Ouvrir dans Google Sheets” qui récupère le fichier sélectionné dans Finder. Cela nécessite une licence payante pour les fonctionnalités avancées.

Script Python seul, sans app

Si tu es à l’aise avec le terminal, tu peux appeler le script directement :

python3 ~/.config/csv_to_sheets/csv_to_sheets.py ~/Downloads/mon_fichier.csv

C’est moins pratique mais fonctionne partout sans aucune configuration d’app.


Conclusion

Cette solution prend 15 minutes à mettre en place, et elle transforme durablement un workflow quotidien pénible. Elle est robuste, fonctionne hors ligne (l’upload se fait à la demande), et ne dépend d’aucune app tierce payante. Le seul prérequis est un compte Google Cloud — gratuit pour cet usage.

Le code est minimaliste et facile à maintenir. Si tu veux l’étendre (support de .ods, upload dans un dossier Drive spécifique, notification macOS après upload), c’est quelques lignes de Python supplémentaires.