Bidirectional data synchronization project between Google Sheets and Excel files with automatic formatting.
English | Русский
- ✅ Export from Google Sheets to Excel with professional formatting
- ✅ Import from Excel to Google Sheets with structure validation
- ✅ Automatic formatting: headers, alignment, borders
- ✅ Conditional formatting: values > 100 highlighted in green
- ✅ Auto-adjust column width based on content
- ✅ Automatic backup before import
- ✅ Data structure validation
- ✅ Error handling with clear logging
- Python 3.10+
- Google Service Account with Google Sheets API access
git clone https://github.com/VernaculusF/excel-gsheets-sync.git
cd excel-gsheets-syncWindows (PowerShell):
python -m venv .venv
.venv\Scripts\Activate.ps1Windows (CMD):
python -m venv .venv
.venv\Scripts\activate.batLinux/macOS:
python3 -m venv .venv
source .venv/bin/activatepip install -r requirements.txt- Go to Google Cloud Console
- Create a new project or select an existing one
- In the navigation menu, select APIs & Services → Library
- Find and enable Google Sheets API
- Go to APIs & Services → Credentials
- Click Create Credentials → Service Account
- Fill in:
- Service account name: e.g.,
excel-sheets-sync - Service account ID: will be auto-generated
- Service account name: e.g.,
- Click Create and Continue
- Role can be left empty (or select Editor)
- Click Done
- In the Service Accounts list, find the created account
- Click on it, go to the Keys tab
- Click Add Key → Create new key
- Select JSON format
- Click Create — the file will automatically download
- Rename the downloaded file to
creds.json - Move the file to the project root folder
- Open the
creds.jsonfile - Find the
"client_email"line, copy the email address"client_email": "excel-sheets-sync@your-project.iam.gserviceaccount.com"
- Open your Google spreadsheet
- Click the Share button
- Paste the email from
client_email - Select Editor role
- Click Send (without notification)
-
Copy
.env.exampleto.env:copy .env.example .env # Windows cp .env.example .env # Linux/macOS
-
Open
.envand fill in:SPREADSHEET_ID=your_spreadsheet_id_here SHEET_NAME=Sheet1
How to get SPREADSHEET_ID:
- Open your Google spreadsheet
- Copy the ID from URL:
https://docs.google.com/spreadsheets/d/1abc_DEFGH-ijk123LMN456opq/edit ^^^^^^^^^^^^^^^^^^^^^^^^ This is your SPREADSHEET_ID
SHEET_NAME:
- Sheet name in the spreadsheet (visible at the bottom of the screen)
- Default:
Sheet1
Export data from Google Sheets to Excel file with formatting:
python sync.py --exportResult:
- Creates file
report_YYYYMMDD_HHMMSS.xlsx - Applies formatting:
- Headers: bold font, gray background
- Auto column width
- Alignment (text left, numbers right)
- Cell borders
- Conditional formatting: cells with value > 100 highlighted in green
Import data from Excel to Google Sheets:
python sync.py --import --file "report.xlsx"With full path:
python sync.py --import --file "C:\Users\user\Documents\data.xlsx"What happens:
- File existence is checked
- Column count is validated against the spreadsheet
- Google Sheets backup is created (new sheet
backup_YYYYMMDD_HHMMSS) - Data is imported (complete overwrite)
excel-gsheets-sync/
├── sync.py # main script with CLI argument parsing
├── sheets_client.py # Google Sheets API operations
├── excel_handler.py # Excel read/write/processing
├── formatter.py # Excel styling configuration
├── config.py # .env configuration loader
├── requirements.txt # Python dependencies
├── .env # environment variables (NOT IN GIT!)
├── .env.example # configuration example
├── creds.json # Google credentials (NOT IN GIT!)
├── creds.json.example # credentials structure example
├── .gitignore # git exclusions
├── README.md # documentation (English)
├── README.ru.md # documentation (Russian)
├── plan.md # development plan
└── .venv/ # virtual environment (NOT IN GIT!)
- Font: bold, 11pt
- Fill: gray color (#D3D3D3)
- Alignment: center
- Borders: thin black
- Alignment:
- Text: left
- Numbers: right
- Borders: thin black
- Cells with value > 100 → green fill (#90EE90)
- Works for all numeric columns
- Applied to all cells except headers
- Minimum width: 10
- Maximum width: 50
- Automatically adjusts to content
To change styles, edit the formatter.py file:
# Headers
HEADER_FONT = Font(bold=True, size=11)
HEADER_FILL = PatternFill(start_color="D3D3D3", ...)
# Conditional formatting
HIGHLIGHT_FILL = PatternFill(start_color="90EE90", ...)
HIGHLIGHT_THRESHOLD = 100 # Highlighting threshold- Saved as empty string
'' - Don't cause synchronization errors
Excel column count must match Google Sheets:
✗ ERROR: Structure mismatch:
Expected: 5 columns
In Excel: 7 columns
A backup is automatically created before import:
✓ Backup created: backup_20260220_143052
The backup is created as a new sheet in the same spreadsheet.
- Make sure the
creds.jsonfile is in the project root - Check that the file is not renamed
- Check the
SPREADSHEET_IDin.env - Make sure the spreadsheet is shared with the email from
creds.json - Check that Google Sheets API is enabled in Google Cloud Console
- Check the sheet name (
SHEET_NAME) in.env - The name must match exactly (including case and spaces)
- Make sure the
.envfile is created and filled - Check for typos in variable names
- Make sure the column count in Excel matches Google Sheets
- Check the first row (headers) in both files
[2026-02-20 14:30:45] [INFO] ============================================================
[2026-02-20 14:30:45] [INFO] MODE: EXPORT (Google Sheets → Excel)
[2026-02-20 14:30:45] [INFO] ============================================================
[2026-02-20 14:30:45] [INFO] Authenticating to Google Sheets...
[2026-02-20 14:30:46] [INFO] ✓ Authentication successful
[2026-02-20 14:30:46] [INFO] Opening spreadsheet...
[2026-02-20 14:30:47] [INFO] ✓ Spreadsheet opened
[2026-02-20 14:30:47] [INFO] Reading data from Google Sheets...
[2026-02-20 14:30:48] [INFO] ✓ Read 150 rows
[2026-02-20 14:30:48] [INFO] Creating Excel file report_20260220_143048.xlsx...
[2026-02-20 14:30:48] [INFO] ✓ Data written
[2026-02-20 14:30:49] [INFO] Applying formatting to Excel sheet...
[2026-02-20 14:30:49] [INFO] ✓ Formatting successfully applied
[2026-02-20 14:30:49] [INFO] ✓ File saved: report_20260220_143048.xlsx
[2026-02-20 14:30:49] [INFO] ============================================================
[2026-02-20 14:30:49] [INFO] ✓ EXPORT COMPLETED
[2026-02-20 14:30:49] [INFO] File: g:\Code\Google Sheets\excel-gsheets-sync\report_20260220_143048.xlsx
[2026-02-20 14:30:49] [INFO] Rows: 150
[2026-02-20 14:30:49] [INFO] ============================================================
[2026-02-20 14:35:12] [INFO] ============================================================
[2026-02-20 14:35:12] [INFO] MODE: IMPORT (Excel → Google Sheets)
[2026-02-20 14:35:12] [INFO] ============================================================
[2026-02-20 14:35:12] [INFO] Reading Excel file data.xlsx...
[2026-02-20 14:35:12] [INFO] ✓ Read 120 rows
[2026-02-20 14:35:12] [INFO] Authenticating to Google Sheets...
[2026-02-20 14:35:13] [INFO] ✓ Authentication successful
[2026-02-20 14:35:13] [INFO] Validating data structure...
[2026-02-20 14:35:14] [INFO] ✓ Excel file structure matches Google Sheets
[2026-02-20 14:35:14] [INFO] Creating backup 'backup_20260220_143514'...
[2026-02-20 14:35:15] [INFO] ✓ Backup created: backup_20260220_143514
[2026-02-20 14:35:15] [INFO] Writing data to Google Sheets (120 rows)...
[2026-02-20 14:35:17] [INFO] ✓ Data successfully written
[2026-02-20 14:35:17] [INFO] ============================================================
[2026-02-20 14:35:17] [INFO] ✓ IMPORT COMPLETED
[2026-02-20 14:35:17] [INFO] File: g:\Code\Google Sheets\excel-gsheets-sync\data.xlsx
[2026-02-20 14:35:17] [INFO] Rows: 120
[2026-02-20 14:35:17] [INFO] Backup: backup_20260220_143514
[2026-02-20 14:35:17] [INFO] ============================================================
.env— contains spreadsheet IDcreds.json— contains Google private keys*.xlsx— Excel data files.venv/— virtual environment
All these files are already added to .gitignore.
- Never commit
creds.jsonto the repository - Don't share
creds.jsonvia messengers or email - Regularly update access keys
- Use minimal access rights for Service Account
Project created for educational purposes.
Developed using GitHub Copilot (Claude Sonnet 4.5)
Happy syncing! 🚀
pip install -r requirements.txt- Перейдите на Google Cloud Console
- Создайте новый проект или выберите существующий
- В меню навигации выберите APIs & Services → Library
- Найдите и включите Google Sheets API
- Перейдите в APIs & Services → Credentials
- Нажмите Create Credentials → Service Account
- Заполните:
- Service account name: например,
excel-sheets-sync - Service account ID: автоматически сгенерируется
- Service account name: например,
- Нажмите Create and Continue
- Роль можно не указывать (или выбрать Editor)
- Нажмите Done
- В списке Service Accounts найдите созданный аккаунт
- Нажмите на него, перейдите на вкладку Keys
- Нажмите Add Key → Create new key
- Выберите формат JSON
- Нажмите Create — файл автоматически скачается
- Переименуйте скачанный файл в
creds.json - Переместите файл в корневую папку проекта:
g:\Code\Google Sheets\excel-gsheets-sync\creds.json
- Откройте файл
creds.json - Найдите строку
"client_email", скопируйте email адрес"client_email": "excel-sheets-sync@your-project.iam.gserviceaccount.com"
- Откройте вашу Google таблицу
- Нажмите кнопку Share (Поделиться)
- Вставьте email из
client_email - Выберите роль Editor (Редактор)
- Нажмите Send (без отправки уведомления)
-
Скопируйте
.env.exampleв.env:copy .env.example .env
-
Откройте
.envи заполните:SPREADSHEET_ID=your_spreadsheet_id_here SHEET_NAME=Sheet1
Как получить SPREADSHEET_ID:
- Откройте вашу Google таблицу
- Скопируйте ID из URL:
https://docs.google.com/spreadsheets/d/1abc_DEFGH-ijk123LMN456opq/edit ^^^^^^^^^^^^^^^^^^^^^^^^ Это ваш SPREADSHEET_ID
SHEET_NAME:
- Название листа в таблице (видно внизу экрана)
- По умолчанию:
Sheet1илиЛист1
Экспортировать данные из Google Sheets в Excel файл с форматированием:
python sync.py --exportРезультат:
- Создается файл
report_YYYYMMDD_HHMMSS.xlsx - Применяется форматирование:
- Заголовки: жирный шрифт, серая заливка
- Автоматическая ширина колонок
- Выравнивание (текст влево, числа вправо)
- Границы всех ячеек
- Условное форматирование: ячейки со значением > 100 выделяются зеленым
Импортировать данные из Excel в Google Sheets:
python sync.py --import --file "report.xlsx"С полным путем:
python sync.py --import --file "C:\Users\user\Documents\data.xlsx"Что происходит:
- Проверяется существование файла
- Проверяется совпадение количества колонок с таблицей
- Создается резервная копия Google Sheets (новый лист
backup_YYYYMMDD_HHMMSS) - Данные импортируются (полная перезапись)
excel-gsheets-sync/
├── sync.py # основной скрипт с парсингом аргументов
├── sheets_client.py # работа с Google Sheets API
├── excel_handler.py # чтение/запись/обработка Excel
├── formatter.py # настройки стилей для Excel
├── config.py # загрузка конфигурации из .env
├── requirements.txt # зависимости Python
├── .env # переменные окружения (НЕ В GIT!)
├── .env.example # пример конфигурации
├── creds.json # учетные данные Google (НЕ В GIT!)
├── creds.json.example # пример структуры ключей
├── .gitignore # исключения для git
├── README.md # документация
├── plan.md # план разработки
└── .venv/ # виртуальное окружение (НЕ В GIT!)
- Шрифт: жирный, 11pt
- Заливка: серый цвет (#D3D3D3)
- Выравнивание: по центру
- Границы: тонкие черные
- Выравнивание:
- Текст: влево
- Числа: вправо
- Границы: тонкие черные
- Ячейки со значением > 100 → зеленая заливка (#90EE90)
- Работает для любых числовых колонок
- Применяется ко всем ячейкам, кроме заголовков
- Минимальная ширина: 10
- Максимальная ширина: 50
- Автоматически подстраивается под содержимое
Чтобы изменить стили, отредактируйте файл formatter.py:
# Заголовки
HEADER_FONT = Font(bold=True, size=11)
HEADER_FILL = PatternFill(start_color="D3D3D3", ...)
# Условное форматирование
HIGHLIGHT_FILL = PatternFill(start_color="90EE90", ...)
HIGHLIGHT_THRESHOLD = 100 # Порог для выделения- Сохраняются как пустая строка
'' - Не вызывают ошибок при синхронизации
Количество колонок в Excel должно совпадать с Google Sheets:
✗ ОШИБКА: Несоответствие структуры:
Ожидается: 5 колонок
В Excel: 7 колонок
Перед импортом автоматически создается резервная копия:
✓ Создана резервная копия: backup_20260220_143052
Копия создается как новый лист в той же таблице.
- Убедитесь, что файл
creds.jsonнаходится в корне проекта - Проверьте, что файл не переименован
- Проверьте правильность
SPREADSHEET_IDв.env - Убедитесь, что таблица расшарена для email из
creds.json - Проверьте, что включен Google Sheets API в Google Cloud Console
- Проверьте название листа (
SHEET_NAME) в.env - Название должно точно совпадать (включая регистр и пробелы)
- Убедитесь, что файл
.envсоздан и заполнен - Проверьте, что нет опечаток в названиях переменных
- Убедитесь, что количество колонок в Excel совпадает с Google Sheets
- Проверьте первую строку (заголовки) в обоих файлах
[2026-02-20 14:30:45] [INFO] ============================================================
[2026-02-20 14:30:45] [INFO] РЕЖИМ: ЭКСПОРТ (Google Sheets → Excel)
[2026-02-20 14:30:45] [INFO] ============================================================
[2026-02-20 14:30:45] [INFO] Авторизация в Google Sheets...
[2026-02-20 14:30:46] [INFO] ✓ Авторизация успешна
[2026-02-20 14:30:46] [INFO] Открытие таблицы...
[2026-02-20 14:30:47] [INFO] ✓ Таблица открыта
[2026-02-20 14:30:47] [INFO] Чтение данных из Google Sheets...
[2026-02-20 14:30:48] [INFO] ✓ Прочитано 150 строк
[2026-02-20 14:30:48] [INFO] Создание Excel файла report_20260220_143048.xlsx...
[2026-02-20 14:30:48] [INFO] ✓ Данные записаны
[2026-02-20 14:30:49] [INFO] Применение форматирования к листу Excel...
[2026-02-20 14:30:49] [INFO] ✓ Форматирование успешно применено
[2026-02-20 14:30:49] [INFO] ✓ Файл сохранен: report_20260220_143048.xlsx
[2026-02-20 14:30:49] [INFO] ============================================================
[2026-02-20 14:30:49] [INFO] ✓ ЭКСПОРТ ЗАВЕРШЕН
[2026-02-20 14:30:49] [INFO] Файл: g:\Code\Google Sheets\excel-gsheets-sync\report_20260220_143048.xlsx
[2026-02-20 14:30:49] [INFO] Строк: 150
[2026-02-20 14:30:49] [INFO] ============================================================
[2026-02-20 14:35:12] [INFO] ============================================================
[2026-02-20 14:35:12] [INFO] РЕЖИМ: ИМПОРТ (Excel → Google Sheets)
[2026-02-20 14:35:12] [INFO] ============================================================
[2026-02-20 14:35:12] [INFO] Чтение Excel файла data.xlsx...
[2026-02-20 14:35:12] [INFO] ✓ Прочитано 120 строк
[2026-02-20 14:35:12] [INFO] Авторизация в Google Sheets...
[2026-02-20 14:35:13] [INFO] ✓ Авторизация успешна
[2026-02-20 14:35:13] [INFO] Проверка структуры данных...
[2026-02-20 14:35:14] [INFO] ✓ Структура Excel файла совпадает с Google Sheets
[2026-02-20 14:35:14] [INFO] Создание резервной копии 'backup_20260220_143514'...
[2026-02-20 14:35:15] [INFO] ✓ Резервная копия создана: backup_20260220_143514
[2026-02-20 14:35:15] [INFO] Запись данных в Google Sheets (120 строк)...
[2026-02-20 14:35:17] [INFO] ✓ Данные успешно записаны
[2026-02-20 14:35:17] [INFO] ============================================================
[2026-02-20 14:35:17] [INFO] ✓ ИМПОРТ ЗАВЕРШЕН
[2026-02-20 14:35:17] [INFO] Файл: g:\Code\Google Sheets\excel-gsheets-sync\data.xlsx
[2026-02-20 14:35:17] [INFO] Строк: 120
[2026-02-20 14:35:17] [INFO] Резервная копия: backup_20260220_143514
[2026-02-20 14:35:17] [INFO] ============================================================
.env— содержит ID таблицыcreds.json— содержит приватные ключи Google*.xlsx— Excel файлы с данными.venv/— виртуальное окружение
Все эти файлы уже добавлены в .gitignore.
- Никогда не коммитьте
creds.jsonв репозиторий - Не делитесь
creds.jsonчерез мессенджеры или email - Регулярно обновляйте ключи доступа
- Используйте минимальные права доступа для Service Account
Проект создан для образовательных целей.
Разработано с использованием GitHub Copilot (Claude Sonnet 4.5)
Успешной синхронизации! 🚀