Skip to content
DevMarket
Odoo ModulesWordPress PluginsWordPress ThemesShopify ThemesApp TemplatesScripts & UtilitiesBlogSell on DevMarket

Bulk Excel Attendance Importer for Odoo 19 documentation

A guide to importing attendance from Excel or CSV: preparing the file, mapping the columns, reading the check, importing, undoing, time zones and troubleshooting.

Documents version 1.0.0Updated Oct 23, 2026

Start here

In plain words: Time clocks, fingerprint devices and spreadsheets all produce the same thing: a list of who came in and when they left. Typing it into Odoo one line at a time takes hours and is full of typos. This module turns that file into attendance records in four steps, and checks every row before anything is created.
Step 3: every row is checked first. Problems are listed at the top, in red.
Step 3: every row is checked first. Problems are listed at the top, in red.
StepWhat you do
1. FileChoose the Excel or CSV file.
2. ColumnsSay which column is the employee, the check-in and the check-out. The module guesses from the titles.
3. CheckSee every row with its status: ready, already in Odoo, or a problem with the reason.
4. ImportThe ready rows become attendances. The rest are left out and can be downloaded as an Excel file to fix.
Tip: Each import is kept as a batch. If something was wrong, one click on Undo this import removes exactly the attendances it created.

Prepare your file

In plain words: The file needs one row per attendance and a title row. It can be .xlsx, .xls or .csv (Arabic CSV files saved by Excel are understood).
Employee IDCheck InCheck Out
E10012026-10-12 08:102026-10-12 17:09
E10022026-10-12 08:122026-10-12 17:03
E10012026-10-13 08:022026-10-13 17:15
RuleWhy
One row per attendanceTwo shifts in a day are two rows.
A title rowThe first row by default. If it is lower, set the Header row.
Real dates and timesExcel dates are best. Text such as 2026-10-12 08:10 or 12/10/2026 8:10 PM also works.
Values, not formulasA formula that Excel has not calculated has no value. Open and save the file in Excel once.
Employees by a stable keyA badge number or an email is safer than a name (see chapter 5).
In plain words: You can also split date and time into separate columns: Date, Time In, Time Out. The module accepts both layouts.

Requirements

ItemDetails
Odoo19.0 (Community or Enterprise)
Apps neededAttendances (hr_attendance)
Who can importUsers with the access right Attendances / Administrator
LicenseOPL-1 (Odoo Proprietary License v1.0)

Install

  1. Unzip the package. Inside is taqnix_attendance_import.zip; unzip it to get the folder taqnix_attendance_import.
  2. Copy the folder into one of the addons_path folders of your Odoo server and restart Odoo.
  3. Log in as an administrator, activate Developer mode, open Apps and press Update Apps List.
  4. Remove the “Apps” filter, search Attendance Importer and press Install.
# or from the command line
./odoo-bin -c odoo.conf -d YOUR_DATABASE -i taqnix_attendance_import --stop-after-init
Tip: A new menu appears: Attendances → Import → Import from Excel / CSV, and Past imports next to it.

How employees are found

In plain words: The file says who with a code, a name or an email. Choose in the first step how the module should find the employee:
Find the employee byMatches the fieldWhere you set it
Badge IDBadge IDEmployee form → HR Settings tab
Identification NoIdentification NoEmployee form → Private Information tab
Work emailWork EmailEmployee form → Work Information
NameEmployee nameEmployee form (spaces and capitals do not matter)
Odoo IDThe database ID of the employeeVisible in the address bar when you open the employee
In plain words: Capitals and extra spaces do not matter. Numbers that Excel stores as numbers (1001) match the text “1001”. If two employees have the same value, the row is refused with a clear message instead of guessing.
Important: Names are the weakest key: two people can share one. Use a badge number if you can.

Step 1: the file

In plain words: Open Attendances → Import → Import from Excel / CSV.
Choose the file and how the employees are identified.
Choose the file and how the employees are identified.
FieldWhat it is
FileYour .xlsx, .xls or .csv.
Find the employee bySee chapter 5.
Sheet numberWhich sheet of the workbook (1 is the first).
Header rowThe row that holds the column titles.
In plain words: Do not have a file yet? Download a sample file gives you a workbook with the right layout.

Step 2: the columns

The module guessed the columns from their titles. Change what is wrong.
The module guessed the columns from their titles. Change what is wrong.
ChoiceMeaning
Employee columnThe column with the code, name or email.
Date column (optional)Use it when the date is in its own column and the check-in/out columns hold only times.
Check-in / Check-out columnDates with times, or only times when there is a date column.
Times in the file are inThe time zone the file was recorded in. Odoo stores UTC and converts for you. Default: your own.
Day before monthRead 03/04/2026 as 3 April. Real Excel dates are not affected.
Night shiftsA check-out earlier than the check-in means the next day (on by default).
Accept rows without a check-outCreate an open attendance. Off by default.
In plain words: The list under the choices shows each column title with the first values, so you can see what is in it. The titles Employee, Badge, ID, Check In, Time In, Check Out, Time Out, Date and the Arabic موظف، دخول، خروج، التاريخ are recognised.

Step 3: check every row

In plain words: Nothing is created yet. Every row gets a status:
StatusMeaning
ReadyWill be imported.
Already thereAn identical attendance is already in Odoo. It is skipped, so importing the same file twice does no harm.
ErrorWill not be imported, with the reason.
MessageWhat to do
No employee found with this valueThe code, name or email is not in Odoo, or you chose the wrong “Find the employee by”.
N employees have this valueTwo employees share it. Use a more precise key.
The date or time is missing or not readableFix the cell (a real date, or text like 2026-10-12 08:10).
There is no check-outAdd it, or accept rows without a check-out.
The check-out is not after the check-inCheck the file. With night shifts on this is rare.
More than 24 hours between check-in and check-outProbably a wrong date.
Overlaps an attendance already in Odoo / Overlaps row NOdoo does not allow overlapping attendances for one person.
In plain words: Errors come first in the list. You can Back to change the columns and check again as often as you like. Import is only possible when at least one row is ready.

Step 4: import, open, undo

In plain words: Press Import the ready rows. The rows that are ready become attendances; rows with errors are left out.
Done: 23 attendances created, the 4 problem rows can be downloaded.
Done: 23 attendances created, the 4 problem rows can be downloaded.
In plain words: Download the failed rows gives an Excel file with the row number, what was in the file and why it failed, so you can correct only those rows and import them again.
The new attendances in the Attendances list.
The new attendances in the Attendances list.
The import is kept as a batch: counts, the failed-rows file and the Undo button.
The import is kept as a batch: counts, the failed-rows file and the Undo button.
On the batchWhat it does
Show the attendancesOpens the attendances created by this import.
Undo this importDeletes exactly those attendances (asks first). The batch stays in the list as “Undone”.
Download the failed rowsThe Excel file of rows that were not imported.
In plain words: Attendances → Import → Past imports lists every import: who, when, how many rows, how many were created and how many failed.
Tip: Odoo then works out the worked hours and the overtime from the attendances in the usual way, the same as for attendances created by hand.

Dates and times it understands

In the fileRead as
A real Excel date and timeAs it is
2026-10-12 08:1012 Oct 2026, 08:10
12/10/2026 8:10 PM with “Day before month”12 Oct 2026, 20:10
12/10/2026 8:10 PM without it10 Dec 2026, 20:10
8:05, 08.05, 8:05 PMA time of day (with a date column)
٢٠٢٦-١٠-١٢ ٠٨:١٠ and ٨:٣٠ مArabic digits and Arabic AM/PM are understood
46307.34 (a number)An Excel date serial number
Only a time in the check-out cellThe date of the check-in is used

Time zones and clock changes

In plain words: Time clocks write local time. Odoo stores UTC. In step 2 choose the time zone the file was recorded in (it starts as your own) and the module converts every row. A time that does not exist or exists twice because of a daylight-saving change is read as standard time instead of failing.
Important: Odoo shows times in the browser's time zone. If you work from another country, the times you see can differ from the file by the difference between the two zones.

Limits

LimitDetail
RowsUp to 20,000 data rows per import. Split bigger files.
SheetsOne sheet per import: choose its number in step 1.
Protected filesPassword-protected workbooks cannot be read: remove the password first.
FormulasTheir calculated values are used, so the file must have been saved by Excel.
Existing attendancesNever changed. Identical ones are skipped, overlapping ones are reported.
One open attendanceOdoo allows one open (no check-out) attendance per employee at a time.

For developers

In plain words: Skip this chapter if you only use the module.
ItemDetails
Modelstaqnix.attendance.import (wizard), taqnix.attendance.import.header, taqnix.attendance.import.line, and the persistent taqnix.attendance.batch.
Linkhr.attendance.taqnix_batch_id points to the batch that created an attendance.
Parsingmodels/parsing.py has plain functions with no database: read_table, parse_datetime, parse_time, parse_date, local_to_utc, guess_columns.
from odoo.addons.taqnix_attendance_import.models import parsing

sheet, headers, rows = parsing.read_table(content, 'march.xlsx')
parsing.parse_time('٨:٣٠ م')       # datetime.time(20, 30)
parsing.local_to_utc(naive_dt, 'Asia/Riyadh')

Troubleshooting

ProblemWhat to do
There is no Import menuYou need the access right Attendances / Administrator.
“The file could not be read”Open it in Excel and save it again as .xlsx, or save as CSV. Remove any password.
All rows say “No employee found”Wrong “Find the employee by”, or the badge IDs are not set on the employees yet.
Times are shiftedCheck “Times in the file are in” (step 2).
Days and months are swappedTick or untick “Day before month” (only for text dates).
Rows say “Overlaps an attendance already in Odoo”The person already has an attendance in that period. Check it in Attendances, or undo the earlier import.
I imported the wrong fileOpen Past imports, open the batch and press Undo this import.

Updating and removing

Replace the folder with the new version, restart Odoo and run -u taqnix_attendance_import. To remove it, uninstall it from Apps. The attendances already imported stay in Odoo as ordinary attendances; the list of past imports is removed.

Support

Installation help and bug fixes are included for 6 months, with lifetime updates. Contact us through the marketplace page where you bought the module or write to support@taqnix.com with your Odoo version and a screenshot.