demo D277
Open a Microsoft Project plan in ESM
Read a Project .xml straight into a schedule, tasks, links, progress and people intact, drawn in the browser, and write it back out again, all with nothing sent to a server
importMSPDI · exportMSPDI
This reads a Microsoft Project XML file straight into a schedule, tasks, links, progress and people intact, draws it in the browser, and writes it back out, all with nothing sent to a server. It lets you open and save real Project plans in the page, so existing plans are not locked away in one tool.
This is the ES module version. The grid is imported straight from a CDN as a module, the same configuration as the vanilla tab without a global script tag, so it drops into any bundler or a bare module script.
The configuration
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.71.0/lattice-grid.min.css">
<div style="margin-bottom: 10px">
<button id="save">Save as Project .xml</button> <span id="status"></span>
</div>
<div id="plan" style="height: 420px; overflow: auto"></div>
<script type="module">
import { createGantt, importMSPDI, exportMSPDI } from '@toclocoinc/lattice-grid/modules/gantt';
// importMSPDI reads a Project .xml into a { tasks, dependencies, resources,
// projectStart, calendar } model: the task tree, typed dependency links with
// their lag, per-task progress and the people on each task.
const model = importMSPDI(xml); // xml: the text of a Project .xml document
document.getElementById('status').textContent =
'Read ' + model.tasks.length + ' tasks and ' + model.dependencies.length + ' links.';
const gantt = createGantt({
tasks: model.tasks,
dependencies: model.dependencies,
resources: model.resources,
projectStart: model.projectStart,
calendar: 'weekends',
autoSchedule: true,
});
gantt.mountSplit(document.getElementById('plan'), {
gridWidth: 300, rowHeight: 34, height: 420, zoom: 'day',
nonWorking: 'weekends', showArrows: true, showProgress: true,
});
// Write the plan back out as a Project file, so a round-trip keeps the tasks,
// typed links and assignments intact. gantt.toMSPDI() is the same over the plan.
document.getElementById('save').addEventListener('click', () => {
const out = exportMSPDI({
tasks: model.tasks,
dependencies: model.dependencies,
schedule: gantt.schedule,
resources: model.resources,
});
const url = URL.createObjectURL(new Blob([out], { type: 'application/xml' }));
const a = document.createElement('a');
a.href = url; a.download = 'plan.xml'; a.click();
URL.revokeObjectURL(url);
});
</script>