What is an XER file, and how do you open one without Primavera P6?
An XER file is the project exchange format written by Oracle Primavera P6. It is a plain tab-delimited text file that carries one or more projects as a sequence of database tables: the project record, its WBS, activities, relationships, calendars, resources and assignments. Because it is text, almost anything can open it. Reading it correctly is the harder part, and most of that difficulty is in durations and calendars.
By the GETSEVEN team · Updated
What an XER file is
An XER file is the native project exchange format of Oracle Primavera P6. When a planner exports a project from P6 Professional or P6 EPPM, the application walks its own database tables, writes the rows that belong to the selected projects, and prefixes each block with the table name and its column headings. Importing is the reverse: P6 reads the blocks back into the same tables. The file is text, the columns are separated by tab characters, and there is no compression or binary section anywhere in it.
That origin explains most of what people find odd about the format. Column names are database column names (target_drtn_hr_cnt, not Original Duration). Every duration, float and lag is stored in hours, because that is how the P6 database stores them. Dates carry a time of day. Activities are linked by internal numeric keys, not by the Activity ID you see on screen. And the file holds the project exactly as the last schedule calculation left it: there is no logic engine inside an XER file, only the results of the one that wrote it.
One file can hold several projects, and it always carries the global data those projects depend on: calendars, resources, currencies, activity code definitions and user-defined field definitions. That is why even a small project exports as a file with a long list of tables, most of which have nothing to do with the schedule itself.
The structure of an XER file
Open an XER file in a text editor and the structure is visible at once. The first line is the header, ERMHDR, followed by the P6 version that wrote the file, the export date, the exporting user, the database name and the base currency. Every line after that begins with one of four markers:
%Tnames a table. Everything until the next%Tbelongs to it.%Flists the table’s field names, one per tab-separated column.%Ris a row of values, in the same column order as the%Fline above it.%Emarks the end of the file.
ERMHDR 21.12 2026-09-30 Project jsmith J Smith P6DB Project Management AUD
%T PROJECT
%F proj_id proj_short_name clndr_id last_recalc_date plan_start_date
%R 4521 PRJ-0142 1234 2026-09-28 08:00 2026-03-02 08:00
%T TASK
%F task_id proj_id wbs_id clndr_id task_code task_name target_drtn_hr_cnt remain_drtn_hr_cnt status_code
%R 88102 4521 3017 1234 A1000 Mobilise to site 80 80 TK_NotStart
%R 88103 4521 3017 1234 A1010 Set out and excavate 120 120 TK_NotStart
%T TASKPRED
%F task_pred_id task_id pred_task_id proj_id pred_proj_id pred_type lag_hr_cnt
%R 55201 88103 88102 4521 4521 PR_FS 0
%EThe separators are tab characters, which is why the file looks ragged in an editor. The example is trimmed: a real TASK table carries far more columns than shown, and a real file carries many more tables. Tables appear in dependency order: currencies and the OBS before PROJECT, calendars and the WBS after it, TASK after those, and TASKPRED and TASKRSRC after TASK. A blank cell is simply nothing between two tabs. A reader has to cope with Windows and Unix line endings, blank lines, and rows that are shorter or longer than their field list, because real exports contain all of these.
Encoding is the first trap. Oracle documents the format as Windows-1252, but newer P6 versions write UTF-8, and some files are a genuine mixture: UTF-8 text with the currency symbols in CURRTYPE, or an older reference table, still written as raw Windows-1252 bytes. Read such a file as pure UTF-8 and those characters become replacement marks; read it as pure Windows-1252 and every accented name written in UTF-8 becomes two or three wrong characters. A careful reader decides line by line.
The tables that matter in an XER file
P6 writes every table the export touches, but a schedule is reconstructed from a handful of them. These are the ones a reader has to understand, and the ones GETSEVEN reads on import.
| Table | What it carries | Fields to know |
|---|---|---|
| PROJECT | One row per project in the file: the Project ID, the default calendar, the planned start and finish, and the data date. | proj_id, proj_short_name, clndr_id, last_recalc_date, plan_start_date, plan_end_date |
| PROJWBS | The WBS tree. The row flagged as the project node is the root and holds the project’s name; every other row points at its parent. | wbs_id, parent_wbs_id, wbs_short_name, wbs_name, seq_num, proj_node_flag |
| TASK | One row per activity: type, status, Activity ID and name, the WBS element it sits under, its calendar, durations, dates, constraints, float and the percent-complete settings. | task_id, task_code, task_name, wbs_id, clndr_id, task_type, status_code, target_drtn_hr_cnt, remain_drtn_hr_cnt, cstr_type, cstr_date, complete_pct_type |
| TASKPRED | Relationships. Each row names a predecessor and a successor by their internal keys, with the type and the lag in hours. | task_pred_id, pred_task_id, task_id, pred_type, lag_hr_cnt |
| CALENDAR | Global, project and resource calendars: hours per day and week as columns, and the weekly working pattern plus exception dates packed into one text column. | clndr_id, clndr_name, clndr_type, day_hr_cnt, week_hr_cnt, base_clndr_id, clndr_data |
| RSRC | The resource pool: labour, non-labour and material, with the resource hierarchy and each resource’s calendar. | rsrc_id, rsrc_short_name, rsrc_name, rsrc_type, parent_rsrc_id, clndr_id |
| RSRCRATE | Resource prices by effective date, up to five rate columns per row, plus the maximum units per hour. | rsrc_id, start_date, cost_per_qty, max_qty_per_hr |
| TASKRSRC | Assignments of resources to activities: planned, remaining and actual quantities and costs, and the assignment’s own dates. | task_id, rsrc_id, target_qty, remain_qty, act_reg_qty, target_cost, act_reg_cost, cost_per_qty |
| FINDATES, TASKFIN, TRSRCFIN | Financial periods, and the actuals stored against each period per activity and per assignment. | fin_dates_id, start_date, end_date, act_work_qty, act_cost |
Beyond these, a typical file also carries CURRTYPE (currencies), OBS, SCHEDOPTIONS (the scheduling options the project was last calculated with), ACTVTYPE, ACTVCODE and TASKACTV (activity codes and their assignments), PCATTYPE, PCATVAL and PROJPCAT (project codes), UDFTYPE and UDFVALUE (user-defined fields) and TASKMEMO (notebook topics). None of them is needed to draw a Gantt chart, but all of them are needed to hand the project back to P6 intact, which is why a good importer keeps the whole file rather than only the parts it understood.
Fields planners ask about
Activity ID versus task_id
task_code is the Activity ID shown in P6 (A1000, CIV-1230). task_id is the database key, unique within the P6 database the file came from, and it is what TASKPRED and TASKRSRC use to point at an activity. A tool matching activities across two files should match on task_code; a tool reading one file follows task_id.
Durations are stored in hours
target_drtn_hr_cnt is the Original Duration, remain_drtn_hr_cnt the Remaining Duration, and total_float_hr_cnt and free_float_hr_cnt the floats, all in hours. The number of hours in a day is not in the TASK table at all; it is on the calendar the activity points to. Lag is the same: lag_hr_cnt on TASKPRED is hours, and a negative value is a lead. The next section is about why this matters.
Dates and the data date
Dates are written as YYYY-MM-DD HH:mm, so every date in the file carries a clock time. The TASK table holds several sets: early and late dates from the last schedule run, target_start_date and target_end_date for the planned dates, act_start_date and act_end_date for actuals, and restart_date and reend_date for the remaining early dates of an activity in progress. The data date lives on the PROJECT row as last_recalc_date, also with a time. Because P6 schedules remaining work from that instant, a reader that drops the time and schedules from midnight can place the first remaining activity on the wrong side of a shift boundary.
Calendars
Every activity has its own clndr_id, and PROJECT has a default clndr_id for activities created without one. A calendar’s clndr_type is global, project or resource. The weekly pattern and the exception dates are packed into clndr_data, a nested bracket notation in which days are numbered 1 for Sunday to 7 for Saturday, shifts appear as s|08:00|f|12:00 pairs, and exceptions are keyed by a spreadsheet-style serial day number. An exception with no shifts is a holiday; one with shifts is a working override, such as a half day. A project or resource calendar may name a base_clndr_id, in which case it stores only its own overrides and inherits the base calendar’s working week and holidays.
Constraints
cstr_type and cstr_date carry the primary constraint; cstr_type2 and cstr_date2 the secondary one. The codes are CS_MSO (start on), CS_MSOA (start on or after), CS_MSOB (start on or before), CS_MEO, CS_MEOA and CS_MEOB for the finish equivalents, CS_MANDSTART and CS_MANDFIN for mandatory dates, and CS_ALAP for as late as possible, which has no date. As soon as possible is simply an empty cell.
Relationships
pred_type is one of PR_FS, PR_SS, PR_FF and PR_SF. A pair of activities may legally carry more than one relationship, typically a start-to-start and a finish-to-finish on overlapping work, so a reader that keys relationships by the pair alone drops the second one. pred_proj_id tells you when the predecessor lives in a different project in the same file.
Which percent complete is real
P6 keeps three measures on every activity, and complete_pct_type says which one is live: CP_Drtn (duration percent, the P6 default, derived from original and remaining duration), CP_Phys (the figure typed into phys_complete_pct) or CP_Units (from act_work_qty and remain_work_qty). Reading phys_complete_pct regardless of the type is a common mistake: on a duration-percent schedule that column is often zero on activities that are finished.
Types and status
task_type distinguishes TT_Task, TT_Rsrc (resource dependent), TT_LOE, TT_Mile and TT_FinMile for start and finish milestones, and TT_WBS for a WBS summary activity. status_code is TK_NotStart, TK_Active or TK_Complete. duration_type carries the four P6 duration types, for example DT_FixedDrtn for fixed duration and units/time and DT_FixedDUR2 for fixed duration and units.
Why durations and calendars are the classic XER import bug
Because durations are hours, every tool that shows days has to divide. The honest divisor is day_hr_cnt on the calendar the activity points to, not a constant. Take a ten-day activity on a standard eight-hour calendar: P6 writes target_drtn_hr_cnt as 80, and 80 divided by 8 is the ten days the planner typed. Now put the same activity on a shutdown calendar working 12-hour shifts. P6 writes 120. Divide by a hard-coded 8 and the activity becomes fifteen days; every remaining duration and every lag on that calendar grows by half, the finish moves, the float changes, and the critical path can change with it. Divide by 12 and the schedule is what the planner built.
The same mistake runs the other way on export. A tool that converts days back to hours at a flat 8 turns ten days on a 12-hour calendar into 80 hours, which P6 then reads as six and two-thirds days. A file that goes out and comes back through such a tool shrinks on every pass.
Three further details catch readers that get the division right:
- Lag has a calendar too. P6’s default scheduling option converts relationship lag on the predecessor’s calendar, so a two-day lag out of a 12-hour activity is 24 hours, not 16. A reader has to look up the predecessor’s calendar before dividing
lag_hr_cnt. - Hours per day is a column, not part of the blob.
day_hr_cntandweek_hr_cntsit as plain columns on CALENDAR. The shifts inclndr_datashould agree with them, but a reader that only parses the blob and assumes eight hours will be wrong on every 10 and 12-hour calendar. - Derived calendars inherit. A project calendar with a
base_clndr_idmay list three exceptions of its own while its base lists several years of public holidays. Ignore the base and those holidays become working days, so every span on that calendar comes out short and the whole downstream network with it.
GETSEVEN’s importer reads day_hr_cnt per calendar, converts each activity’s durations on its own calendar and each lag on the predecessor’s, adds a base calendar’s holidays to a derived calendar’s own, and keeps the shift windows rather than collapsing a day to a single block. Its exporter converts back on the same calendars.
How to open an XER file without P6
Any text editor opens an XER file, because it is text. Whether that is useful depends on what you want from it.
- Primavera P6 itself. The only reader guaranteed to interpret every table the way the writer meant. P6 Professional imports an XER from the File menu; the wizard lists the projects in the file and lets you create new projects or update existing ones. If you have a licence, this is the answer.
- A text editor. Fine for a look at the header, the project list or a single value. Hopeless for reading a schedule, because the TASK table is wide, keys are numbers, and dates and durations need other tables to make sense.
- Excel. Excel opens a tab-delimited file, so the whole XER lands in one sheet with every table stacked vertically and each table’s
%Fline serving as a header for the rows beneath it. That gives you the raw cells, nothing more: no WBS tree, no connection between a relationship row and the activities it names, hours rather than days, and Excel’s habit of reformatting anything that looks like a date or a number. For a quick count of activities or a scan of Activity IDs it works. Treat it as a way to read, never as a way to edit and send back: a file saved out of Excel will usually have been altered in ways P6 rejects. - Third-party viewers and converters. A number of desktop and web tools read XER and show a Gantt chart or export a spreadsheet, and the open-source MPXJ library reads the format for developers. Quality varies on exactly the points above: hours per day, calendar inheritance, which percent complete is live. Test any of them with an activity on a non-standard calendar before trusting a date.
- A scheduling tool with a real importer. GETSEVEN imports an XER into a full schedule: WBS, activities, logic, calendars, resources, assignments and financial periods, with the dates, durations and progress the file carries. Nothing is rescheduled on the way in, so the first view of the project is the one P6 last calculated; a reschedule happens only when you ask for it. The Data Exchange page lists what the import reads and what it does not.
XER to Excel
If what you need is a spreadsheet of the schedule rather than the raw file, convert after a proper import rather than before. The Excel export from GETSEVEN writes the activity register as a sheet, with an ID column first and a Delete column last so the same workbook can be edited and re-imported; resource, assignment, cost-type, cost-assignment and risk sheets follow the same contract. It does not carry the WBS tree, relationships or calendars, so it is a register, not a second copy of the schedule. For the raw tables, the text-editor and Excel routes above remain the honest way to see exactly what P6 wrote.
XER vs P6 XML vs MSPDI
Three text formats move schedules between tools, and they are not interchangeable.
| Format | Written by | Carries | Read by |
|---|---|---|---|
| XER | Primavera P6 Professional and P6 EPPM | Projects with their activities, logic, calendars, resources, assignments, codes, user-defined fields and financial periods, plus the global data they depend on. No baselines, no layouts. | P6, and the many third-party tools that parse the tab-delimited tables |
| P6 XML | Primavera P6 | The same project data in Oracle’s XML schema, with the option to include the project’s baselines. | P6; far fewer third-party tools |
| MSPDI | Microsoft Project, via Save As XML | A Project plan in Microsoft’s schema: tasks, outline, links, calendars, resources, assignments and baselines. | Microsoft Project, P6 through its Microsoft Project import, and many other tools |
Three points decide which one to ask for:
- Baselines. An XER carries the projects you select and nothing of their baselines. To move a baseline by XER, the baseline is restored as a project in P6 and exported in its own right. P6 XML can carry baselines with the project.
- Tool support. XER is the format most third-party tools read, because it is tab-delimited text with a stable table layout. P6 XML is better supported inside the Oracle products than outside them. MSPDI is the format to use when the other party is on Microsoft Project; a binary .mpp file is not readable outside Microsoft Project and a few libraries, so ask for the XML.
- Fidelity across vendors. Every conversion between P6 and Microsoft Project loses something, because the two schedulers do not share a model: P6 has activity types, two constraints per activity and a percent-complete type; Project has task modes, a single constraint and its own calendar structure. A schedule that has to live in both tools should be built with the overlap in mind.
GETSEVEN reads XER and MSPDI. It does not read P6 XML, and it cannot open a binary .mpp file; Microsoft Project users save as XML first.
What a faithful XER round trip requires
A planner who imports an XER, updates it and sends it back is asking for more than an import. The file that goes back has to open in P6 with the changes applied and nothing else disturbed: the activity codes, user-defined fields, notebook topics, cost accounts and project codes that the editing tool never showed must all still be there. There are two ways to get that. The first is to model everything P6 models, which no tool other than P6 does. The second is to keep the original file and patch it.
GETSEVEN takes the second route. The imported file is retained verbatim on the project record. On export it is parsed again and only the cells the application is responsible for are rewritten: on TASK, the dates, actual dates, original and remaining durations, percent complete, status, both constraints and the duration and percent-complete types; on TASKPRED, the relationship type and lag, with relationships added or removed in the application reconciled against the file; and on PROJECT, the data date. Durations and lags are converted back to hours on the same calendars they were read with, the percent complete is written to the column that complete_pct_type nominates, and every other table in the file is written out as it came in. An exported file re-imported and rescheduled lands on the same dates, and that round trip is regression-tested against real Primavera P6 exports.
Two limits follow from the design, and they are worth knowing before you rely on it:
- Structural edits are not written back into a retained file. Activities and WBS elements added in the application after the import, renamed activities, and changes to resources or assignments are outside the patched set. The round trip is for statusing and schedule changes, not for rebuilding the project.
- A project created natively has no source file to patch. Its XER export is a synthesised minimal document: currency, work calendars, OBS, the project row, the WBS, activities with their dates, durations, constraints and progress, and the relationships. It imports into P6, but carries no resources, roles, user-defined fields or costs, and progress is written as physical percent complete so that it survives the import. The same minimal form is used when an XER import is exported as MSPDI, or the reverse, because the retained file is in the other format.
Each import is capped at 25 MB per file. Once imported, the project behaves like any other: the Activities view is the register and Gantt chart, and the DCMA checks run the 14-point assessment on the imported logic, which is the usual first thing to do with a schedule received from another party. If you would rather see it than read about it, book a demo and bring a file.
Questions
What is an XER file?
An XER file is the project export format of Oracle Primavera P6. It is a tab-delimited text file containing the P6 database tables for one or more projects, together with the calendars, resources, codes and user-defined fields those projects depend on.
How do I open an XER file without Primavera P6?
Any text editor or Excel will show the raw tables, but not the schedule. To see the WBS, Gantt chart and logic you need a tool with an XER importer that converts hours to days on each activity’s own calendar; GETSEVEN’s Data Exchange import is one.
Can I open an XER file in Excel?
Yes. Excel reads the tab-delimited text and stacks every table in one sheet, with each %F line acting as the header for the rows beneath it. You get raw cells with durations in hours and activities linked by numeric keys, and a file saved back out of Excel is usually no longer a valid XER.
What is the difference between an XER file and a P6 XML file?
Both are written by Primavera P6 and carry the same project data. XER is tab-delimited text that most third-party tools can read but which carries no baselines; P6 XML uses Oracle’s XML schema, can include baselines, and is read mainly by P6 itself.
Why are durations wrong after importing an XER file?
P6 stores every duration, float and lag in hours, and the hours in a working day are on the activity’s calendar, not on the activity. A tool that divides by a fixed eight stretches every activity on a 10 or 12-hour calendar; a correct import divides by that calendar’s day_hr_cnt and converts lag on the predecessor’s calendar.
Does an XER file contain baselines?
No. An XER export carries the projects you select and not their baselines. To move a baseline as an XER, restore it as a project in P6 and export that project; P6 XML can carry baselines with the project.
Which field in an XER file is the data date?
The data date is last_recalc_date on the PROJECT table, written with a time of day. It is the instant P6 scheduled remaining work from, and a reader that discards the time can shift the first remaining activity across a shift boundary.
Can I edit an XER file in GETSEVEN and send it back to P6?
Yes, for schedule and status changes. The original file is retained on import, and the export rewrites only the dates, durations, progress, status, constraints, relationships and data date in it, leaving every other table as it came in. Activities or WBS elements added after the import are not written into a retained file.
Where this lives in GETSEVEN
Data Exchange
Read and write Primavera XER and MS Project MSPDI, round-trip Excel against a strict re-import contract, and print the Gantt to a real paged PDF.
Activities
The critical-path Gantt where the schedule is actually built — a virtualised table and timeline that computes your dates from logic, calendars and constraints instead of letting you type them.
Projects
The portfolio register — an EPS tree, full project CRUD, and one place to open, duplicate, or promote a what-if scenario into a real project.
DCMA Checks
Run the DCMA 14-point assessment against your live schedule, a stored project, or a client’s XER — before they run it on you.
Send us an XER file and watch it import
Bring a real export, including the awkward one with 12-hour calendars and a mixed encoding. We will import it live, walk through what came across, and show you the file that goes back to P6.