Click or drag to resize

SAF (Excel)

[This is preliminary documentation and is subject to change.]

We provide the option to import/export a model defined in ADM from/to SAF (= Excel)

  1. Install NuGet package ModelExchanger.Excel and it's dependencies.

  2. Use ExcelModuleBootstrapper to bootstrap the Excel module and gain access to an IScopedServiceProvider, used to resolve services.

  3. Fetch an instance of IExcelWriter using IScopedServiceProvider if you want to export an AnalysisModel to Excel.

  4. Fetch an instance of IExcelReader using IScopedServiceProvider if you want to import an AnalysisModel from Excel.

Version history

Here we will outline the most significant changes based on each release.


  • Upated the SAF SDK to 1.3.1

  • Added mapping profile for ResultAnalysisInternalForces2D


  • Updated the SAF SDK to 1.1.0

  • Updated mapping for new Definition property on StructuralManufacturedCrossSection


  • Updated the SAF SDK to 1.1.0-beta.1


  • Updated the SAF SDK to 1.1.0-preview-if1d0012

  • Updated ExcelImportControl with new NamesToIdMapping property, which will be used during import to apply ADM IDs on existing objects that do not have a ID (because the source application for the SAF file does not support IDs)

  • Updated mapping for StructuralParametricCrossSection, StructuralCompoundCrossSection, StructuralCombinationCrossSection to round parameter values to a maximum of 5 digits.

    This was done because these values are put into a single cell with a separator and there was a possibility of values with a lot of decimals which would make the cell look bloated.

  • Updated mapping for StructuralCurveActionFree to deal with the rename of Value1 to Value in the SAF SDK

  • Updated mapping for StructuralCurveAction to deal with the rename of Value1 to Value in the SAF SDK

  • Updated mapping for StructuralSurfaceMember's Thickness to round the thickness values when exporting to have a maximum of 5 decimals.

    Same reason as with the cross-sections

  • Updated global mapping profile to grab an ID for an object when mapping from SAF to ADM, when the NamesToIdMapping is provided on the ExcelImportControl and the name of the object exists in the mapping table.

    If the mapping table does not contain the name of the object, or the mapping table is not provided, we keep the ID that was provided in the Excel file or the one that was generated by the SDK


  • Updated SAF SDK to 1.1.0-preview-if1d0011

  • Added new object, ExcelImportControl, that allows you to control the import of a SAF file

  • Updated the IExcelReader: Marked the current Read as obsolete and added new Read variant that uses the new ExcelImportControl object.

  • Updated mapping for StructuralCurveAction to add support for loads on opening edges and subregion edges

  • Updated mapping for StructuralCurveMoment to add support for loads on opening edges and subregion edges

  • Added mapping for StructuralCurveActionThermal

  • Added mapping for StructuralSurfaceActionDistribution

  • Updated mapping for StructuralSurfaceAction to support the new reference to StructuralSurfaceActionDistribution and provide a value for ForceAction property which only exists on the SAF object

  • Updated mapping for ResultAnalysisInternalForces1D to support the CombinationKey property, as it was previously being ignored

  • Updated mapping for RelConnectsSurfaceEdge to support 0- or 1-based indexing, caused by a typo in the SAF specs. See for more information

  • Updated mapping for StructuralSurfaceMemberOpening so that it gets added to the reference dictionary after mapping has completed to ADM, since it can now be referenced by other objects

  • Updated mapping for StructuralLoadCombination so that it also maps the new Type property.


  • Extracted the DataAccess part of the module in the new StructuralAnalysisFormat SDK, hosted on GitHub

    It can be found at

    If you require access, please get in touch.

  • Updated the conversion layer to work with the new SDK

  • Removed usage from any ADM related types (mainly enums) as well


  • Updated supported SAF versions to also include 1.0.7, 1.0.8, 1.0.9 and 2.0.0 but we are far from supporting all features from all these versions!

  • Added support for direction vector on loads (2.0.0)

  • Added support for virtual eccentricities (1.0.6)

    For StructuralCurveMember, the old eccentricity columns ("Eccentricity ey" and "Eccentricity ez") remain valid for versions prior to 1.0.6. Exporting a newer version to an older version will use the max values of the Analysis eccentricity properties for the old eccentricity properties.

    For StructuralSurfaceMember, the old "Eccentricity ez" column has been replaced with "Analysis Z Eccentricity" and a new "Structural Z Eccentricity" column has been added. The old "Eccentricity ez" column remains valid for version prior to 1.0.6

  • Updated headers on StructuralSurfaceActionThermal for Value1 and Value2. They are now "TempT" and "TempB", according to the 1.0.6 specification. The headers "T1" and "T2" remain supported for version lower than 1.0.6

  • Changed default translation for curve distribution "Trapezoidal" to "Trapez" when exporting. Both are still valid when importing.

  • Changed default translation for load type "Standard" to "Others" when exporting. Both are still valid when importing.


  • Updated to AutoMapper 10.1.1

  • Switched to new ModelExchanger.Tools.Excel package for Excel interop.

  • Fixed issue with Thickness validation on StructuralSurfaceMember. It will only be validated when Thickness Type is set


  • Added IExcelVersionService, which returns a list of supported SAF versions.

  • Added ExcelReadResult object, which contains an ImportResult, along with the version of SAF used for the import.

  • Added ReadWithInfo method to IExcelReader, which returns an ExcelReadResult

  • Fixed issue with 'Node' on RelConnectsRigidMember, which was not being resolved properly when importing.

  • Fixed issue with extra spaces in the names of reference objects on RelConnectsRigidMember properties, causing the import to fail.

  • Added missing formats on several numeric properties on several objects. Every column in the excel file which is a number should now also have a format and be marked as a 'Number' column instead of 'General'.

  • Fixed issue with parsing StructuralSurfaceMember thickness values coming from different cultures when importing.

  • Fixed issue with StructuralSurfaceMember thickness values not being converted to culture invariant strings when exporting.

  • Added support for importing and exporting arrays of integer, guid, datetime, version and strings. Before, we only supported double arrays.

  • Fixed validation for 'WithFor' properties on StructuralCurveMemberRib. They are now as described in the SAF documentation.

  • Added validation rules for 'Resistance' properties on constraints that are 'NonLinear'.

  • Fixed issue with StructuralSurfaceActionFree definition values not being converted to culture invariant strings when exporting.

  • Updated StructuralCrossSection properties to use units instead of doubles. Now these properties also support metric / imperial.


The excel module has received a significant update in this version: Version support on object, property and header level.

We are now capable of defining which objects are compatible with a SAF version, which properties on an object are compatible with a SAF version and which header corresponds to a SAF version.

We noticed a lot of discrepancies between what was defined in the SAF documentation concerning headers and what was implemented. With this update, we can now support multiple headers for a single column

  • Removed Read(Stream) : AnalysisModel method from IExcelReader. It was marked as obsolete since 0.9.1

  • Added Read(Stream, Version) : ExcelModel method to IExcelReader to support our efforts of making our excel module available for all 3rd parties. Please note that this is currently an experimental work in progress.

  • Added version support throughout the import and export workflow.

    In context of ADM, the import will always happen to the latest SAF version. When exporting an ADM to SAF, it is now possible to choose a target SAF version.

  • Added Write(Stream, ExcelModel, Version, Version) method to IExcelWriter to support our efforts of making our excel module available for all 3rd parties. Please note that this is currently an experimental work in progress.

  • Fixed issue with our wrapper around EPPlus that would prevent multiple files to be read in the same scope. The wrapper was caching worksheets from the file it previously opened.

  • Bumped supported SAF version to 1.0.6, although it is not yet completely implemented.

  • Updated enum translations to correspond with what was defined in the SAF documentation. Kept support for the wrong values, so that files that have been previously generated will still work.

  • Updated validator for StructuralSurfaceMember: Type is no longer required and will receive a default value of Plate when left blank.

  • Updated validator for Color: It was too strict, as alpha channel values had to be included (e.g. #AARRGGBB). But now we also allow values without alpha channel (e.g. #RRGGBB), and assume an alpha channel value of FF when omitted.


  • Fixed issue that would cause a validation error to be generated for columns that should have a unit specified in the header, but was missing the unit header.

    It's now possible to omit units in the headers, but it's not recommended.

    E.g. before a column with header "Coordinate X [m]" could not be imported as "Coordinate X". Now this is possible.

  • Disabled generating validation messages using column headers from the file being imported for now. It was causing issues and needs to be investigated further.

    For now it will use "humanized" property names until a fix is in place.


  • Added support for ParentId properties on additional affected objects

  • Added compatibility on StructuralCrossSection for SAF v1.0.6: Old FormCode values are remapped automatically to their new equivalent when importing an older version SAF

  • Fixed export value for LocalCoordinateSystem enum values. By default, we added spaces between the cases (e.g. MinusZYX would become Minus ZYX) but this was not wanted. Now the values are exported as they are defined on the enum.


  • Fixed issue when trying to import cross-sections. In some cases, the type of cross-section was not properly recognized due to case-sensitivity

  • Improved validation message when parsing the value of a column into an enum was not successful.

  • Improved validation messages when something went wrong while trying to map from Excel to ADM

  • Fixed issue where a non-breaking space character (160) would not be recognized as a normal space (32) when parsing column / row headers

  • Fixed issue when importing excel file with a wrong system of units defined on the model sheet. It will now correctly default to Metric if the parsing failed.

  • Added support for ParentId and Area properties on affected objects

  • Added support for LocalCoordinateSystem property on Model sheet. It will default to ZYX

  • Updated excel wrapper (used to retrieve / write values to the actual excel file) to trim strings when read from the file.


  • Fixed issue with double parsing on StructuralSurfaceActionFree in the Q column

  • Added support for StructuralCurveMemberVarying and StructuralStorey

  • Fixed issue with reference validation, when combining multi-reference in multi-reference fields


  • Added support for StructuralProxyElement import and export

  • Updated IExcelReader: Instead of returning a AnalysisModel it now returns an ImportResult. This is to facilitate the ability to allow validation results from Excel to be transferred across module, but no longer be a part of an AnalysisModel. See 0.9.1 patch notes for more information

  • Additional to the aforementioned API change, IExcelReader now also accepts an additional parameter that allows you to import invalid models and allow you to correct these models through code. By default, it will still throw an exception if there are any validation results with severity Error

  • Deleted code that was marked obsolete a while ago

  • Marked old call in IExcelReader to Read as obsolete. Will be removed in later version

  • Added support for reading and writing multiple tables on a single sheet


  • Removed Specification from load case


  • Added support for metric & imperial export or import. Before, only metric units were supported.

  • Added support for compatibility when importing or export for different version.


  • Added support for some new objects that were added to ADM