A small Python script that converts a Microsoft Planner Excel export into a JSON file you can import directly into Nextcloud Deck.
Export the plan from Planner. Run the script. Import the JSON in Deck. That's it.
There is no official migration path from Microsoft Planner to Nextcloud Deck. I wanted to move a board out of Planner without retyping a few dozen cards by hand, so I wrote this.
Disclaimer: I'm not a Python developer. I had a clear idea of what I wanted, and I used Claude Code to help with the actual implementation. All changes were reviewed and tested against a real Nextcloud instance before publishing.
- Buckets become Stacks
- Tasks become Cards in the matching Stack
- Notes go into the card description
- Labels become board-wide with card references
- Due dates are converted to ISO-8601
- Status "Completed" sets the card's done flag
- Priority and start date are added to the card description
- Checklist items become Markdown checkboxes in the description, including completion state
- Assignments. M365 user IDs don't map to Nextcloud usernames.
- Comments and attachments. Microsoft doesn't include them in the Excel export.
Microsoft generates the Excel centrally, so the order of sheets and columns is constant across all languages. Only the header texts are localized. The script reads everything by position, which means it works for any language Planner is available in. The only string match is for the "Completed" status, since Deck needs the done flag to be set explicitly. The script knows that word in seven languages already; add yours to DONE_STATUS_VALUES if it's missing.
| Component | Version |
|---|---|
| Nextcloud Server | 33.0.5 |
| Nextcloud Deck | 1.17.1 |
| Microsoft Planner | on 3rd June 2026 |
Planner has no user-facing version number, so a successful test date is the closest thing. If things break later, Microsoft probably changed the export schema or Deck changed its JSON structure. The constants at the top of the script tell the parser where to look; that's where to start adjusting.
- Python 3.7+
openpyxl
sudo apt install python3-openpyxl
Or via pip: pip install openpyxl.
Export the plan from Planner via ... -> Export plan to Excel. Then:
Important
The owner argument (here "Jane Doe") must match an existing Nextcloud username exactly. If it doesn't, the import will succeed silently but the board won't show up for anyone.
$ python3 planner_to_nextcloud_deck.py board.xlsx "Jane Doe"
Reading board.xlsx ...
Sheets: ['Plan', 'Consolidated Data', 'Tasks', 'Goals', 'Buckets', 'Users']
5 buckets: ['Backlog', 'Planned', 'In Progress', 'Waiting', 'Done']
8 tasks
Plan name: My Board
Done: board.json
Board: My Board
Owner: Jane Doe
Stacks: 5
Cards: 8 (1 done)
Labels: 3
Then in Nextcloud Deck: "Import board" -> pick the JSON.
| Argument | What it does |
|---|---|
<input> |
Path to the Planner Excel file. Required. |
<owner> |
Nextcloud username that will own the board. Required. |
[output] |
Path to the output JSON file. Defaults to the input name with .json extension. |
--color |
Board color as hex without #. Default 0082c9. |
--quiet |
Suppress status output. |
- Read the Excel and check it looks like a Planner export (number of sheets, column count)
- Collect all bucket names from the Buckets sheet, in order
- Walk all tasks once to collect labels board-wide
- Walk all tasks a second time to create cards in the right stack, with description, labels, due date and done flag
- Wrap everything in the JSON structure Deck expects and write it out
The script writes IDs starting from 1. Deck assigns new IDs on import, so collisions don't matter.
This project was developed with the help of Claude Clode. I described what I wanted, Claude wrote the code, and the Deck import format was figured out by reverse engineering a real export. All changes were reviewed and tested against a real Nextcloud instance before publishing.
Not affiliated with Microsoft or Nextcloud GmbH. "Microsoft Planner" and "Nextcloud" are trademarks of their respective owners. Back up your Nextcloud instance before importing.