MpxjEx (MpxjEx v0.1.0)

Copy Markdown View Source

Read Microsoft Project, Primavera and other schedule files, powered by MPXJ.

{:ok, project} = MpxjEx.read("plan.mpp")

project.properties.project_title
#=> "Office move"

for task <- project.tasks, do: {task.name, task.start, task.finish}

read/2 returns an MpxjEx.Project holding tasks, resources, assignments, dependencies and calendars. convert/3 converts a file to another format.

The file format is detected from the content. MPXJ reads, among others: MPP, MPX, MSPDI (MS Project XML), Primavera XER, PMXML, P3 and SureTrak, Asta Powerproject, Phoenix, FastTrack, GanttProject, Planner, ConceptDraw, Synchro, Deltek Open Plan and Edraw Project.

Requirements

MPXJ is a Java library, so a Java runtime (8 or newer) must be installed. MPXJ itself is downloaded on first use, see MpxjEx.Installer.

Each call starts a JVM, which takes around half a second. To read many files, run an MpxjEx.Server.

Options

read/2, read_all/2 and convert/3 accept:

  • :server - an MpxjEx.Server to send the request to, instead of starting a JVM. Defaults to config :mpxj_ex, :server.
  • :timeout - how long to wait for an MpxjEx.Server, in milliseconds (default 60_000)
  • :max_memory - JVM maximum heap size, such as "2g", when no server is used
  • :java - path to the java executable
  • :jvm_args - extra arguments for the JVM

read/2 and read_all/2 also accept:

  • :time_units - unit for durations, work and lags: :seconds (default), :minutes, :hours, :days, :weeks, :months or :years. Durations are converted using the task's calendar, so with :days an 8 hour task on a standard calendar is 1.0.
  • :timephased - include timephased work and cost data (default false)
  • :raw - return the JSON MPXJ produced, decoded but otherwise untouched

Summary

Functions

Converts a schedule file to another format.

Reads a schedule file.

Same as read/2, but raises MpxjEx.Error on failure.

Reads every project in a file.

Same as read_all/2, but raises MpxjEx.Error on failure.

Types

format()

@type format() :: :mspdi | :mpx | :xer | :pmxml | :planner | :sdef | :json

time_unit()

@type time_unit() ::
  :minutes
  | :hours
  | :days
  | :weeks
  | :months
  | :years
  | :percent
  | :elapsed_minutes
  | :elapsed_hours
  | :elapsed_days
  | :elapsed_weeks
  | :elapsed_months
  | :elapsed_years
  | :elapsed_percent

Functions

convert(input, output, opts \\ [])

@spec convert(Path.t(), Path.t(), keyword()) :: :ok | {:error, MpxjEx.Error.t()}

Converts a schedule file to another format.

The output format comes from the :format option, or else from the output file extension:

FormatExtensionDescription
:mspdi.xmlMicrosoft Project XML
:mpx.mpxMicrosoft Project exchange format
:xer.xerPrimavera P6 XER
:pmxml.pmxmlPrimavera P6 XML
:planner.plannerGNOME Planner
:sdef.sdefStandard Data Exchange Format
:json.jsonMPXJ's JSON

MPXJ can't write MPP files.

See the module documentation for the other options.

Examples

:ok = MpxjEx.convert("plan.mpp", "plan.xml")
:ok = MpxjEx.convert("plan.mpp", "plan-p6.xml", format: :pmxml)

convert!(input, output, opts \\ [])

@spec convert!(Path.t(), Path.t(), keyword()) :: :ok

Same as convert/3, but raises MpxjEx.Error on failure.

read(path, opts \\ [])

@spec read(Path.t(), keyword()) ::
  {:ok, MpxjEx.Project.t() | map()} | {:error, MpxjEx.Error.t()}

Reads a schedule file.

When a file holds several projects (as Primavera XER and PMXML files can), this returns the first one; use read_all/2 to get them all.

See the module documentation for the options.

Examples

{:ok, project} = MpxjEx.read("plan.mpp", time_units: :hours)
{:error, %MpxjEx.Error{reason: :file_not_found}} = MpxjEx.read("missing.mpp")

read!(path, opts \\ [])

@spec read!(Path.t(), keyword()) :: MpxjEx.Project.t() | map()

Same as read/2, but raises MpxjEx.Error on failure.

read_all(path, opts \\ [])

@spec read_all(Path.t(), keyword()) ::
  {:ok, [MpxjEx.Project.t() | map()]} | {:error, MpxjEx.Error.t()}

Reads every project in a file.

See the module documentation for the options.

read_all!(path, opts \\ [])

@spec read_all!(Path.t(), keyword()) :: [MpxjEx.Project.t() | map()]

Same as read_all/2, but raises MpxjEx.Error on failure.