diff --git a/pom.xml b/pom.xml
index b8ceac8b56308f61e77674966d403e3ff546f112..2c64c2310d53ccf0989d634cf62b8afcd3eeab37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,6 +65,11 @@
       <artifactId>findbugs-annotations</artifactId>
       <version>3.0.1</version>
     </dependency>
+    <dependency>
+        <groupId>org.apache.poi</groupId>
+        <artifactId>poi-ooxml</artifactId>
+        <version>5.2.2</version>
+    </dependency>
 
     <dependency>
       <groupId>org.springdoc</groupId>
diff --git a/src/main/java/org/openepics/names/rest/api/v1/INames.java b/src/main/java/org/openepics/names/rest/api/v1/INames.java
index 45f9112c639c804750ea0922d9024969ef1ee98d..70f80fc723276e75e60ee360f979c0b9df5e785f 100644
--- a/src/main/java/org/openepics/names/rest/api/v1/INames.java
+++ b/src/main/java/org/openepics/names/rest/api/v1/INames.java
@@ -27,6 +27,8 @@ import org.openepics.names.rest.beans.response.Response;
 import org.openepics.names.rest.beans.response.ResponseBoolean;
 import org.openepics.names.rest.beans.response.ResponseBooleanList;
 import org.openepics.names.rest.beans.response.ResponsePageNameElements;
+import org.openepics.names.util.ExcelUtil;
+import org.springframework.core.io.Resource;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -36,6 +38,7 @@ import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
 
 import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.Operation;
@@ -61,22 +64,23 @@ public interface INames {
     /*
        FieldName   - UUID, NAME, NAMEEQUIVALENCE, SYSTEMSTRUCTURE, DEVICESTRUCTURE, DESCRIPTION
 
-       NameElement - uuid               (UUID)
-                     systemgroup        (UUID)
-                     system             (UUID)
-                     subsystem          (UUID)
-                     devicetype         (UUID)
-                     systemstructure    (String)(mnemonic path)
-                     devicestructure    (String)(mnemonic path)
-                     index              (String)
-                     name               (String)
-                     description        (String)
-                     status             (Status)
-                     latest             (Boolean)
-                     deleted            (Boolean)
-                     when               (Date)
-                     who                (String)
-                     comment            (String)
+       NameElementCommand - subset of NameElement attributes
+       NameElement
+                     uuid                     (UUID)
+                     parentsystemstructure    (UUID)
+                     parentdevicestructure    (UUID)
+                     index                    (String)
+                     description              (String)
+                     comment                  (String)
+                     ----------------------------------
+                     systemstructure          (String)
+                     devicestructure          (String)
+                     name                     (String)
+                     status                   (Status)
+                     latest                   (Boolean)
+                     deleted                  (Boolean)
+                     when                     (Date)
+                     who                      (String)
 
        authentication/authorization
            3 levels - no, user, administrator
@@ -85,29 +89,34 @@ public interface INames {
              ( administrator )
 
        Methods
-           create    POST   /names                                - createNames(List<NameElementCommand>)
+           create    POST   /names                                - createNames                  (List<NameElementCommand>)
+           create    POST   /names/upload                         - createNames                  (MultipartFile)
            ----------------------------------------------------------------------------------------------------
-           read      GET    /names                                - readNames(Boolean, FieldName[], String[], FieldName, Boolean, Integer, Integer)
-           read      GET    /names/{name}                         - readNames(String, FieldName, Boolean, Integer, Integer)
-           read      GET    /names/systemstructure/{mnemonicpath} - readNamesSystemStructure(String, FieldName, Boolean, Integer, Integer)
-           read      GET    /names/devicestructure/{mnemonicpath} - readNamesDeviceStructure(String, FieldName, Boolean, Integer, Integer)
-           read      GET    /names/history/{uuid}                 - readNamesHistory(String, FieldName, Boolean, Integer, Integer)
+           read      GET    /names                                - readNames                    (Boolean, FieldName[], String[], FieldName, Boolean, Integer, Integer)
+           read      GET    /names/download                       - readNamesDownload            (Boolean, FieldName[], String[], FieldName, Boolean, Integer, Integer)
+           read      GET    /names/{name}                         - readNames                    (String, FieldName, Boolean, Integer, Integer)
+           read      GET    /names/systemstructure/{mnemonicpath} - readNamesSystemStructure     (String, FieldName, Boolean, Integer, Integer)
+           read      GET    /names/devicestructure/{mnemonicpath} - readNamesDeviceStructure     (String, FieldName, Boolean, Integer, Integer)
+           read      GET    /names/history/{uuid}                 - readNamesHistory             (String, FieldName, Boolean, Integer, Integer)
            ----------------------------------------------------------------------------------------------------
-           read      GET    /names/equivalence/{name}             - equivalenceName(String)
-           read      GET    /names/exists/{name}                  - existsName(String)
-           read      GET    /names/islegacy/{name}                - isLegacyName(String)
-           read      GET    /names/isvalidtocreate/{name}         - isValidToCreateName(String)
+           read      GET    /names/equivalence/{name}             - equivalenceName              (String)
+           read      GET    /names/exists/{name}                  - existsName                   (String)
+           read      GET    /names/islegacy/{name}                - isLegacyName                 (String)
+           read      GET    /names/isvalidtocreate/{name}         - isValidToCreateName          (String)
            ----------------------------------------------------------------------------------------------------
-           read      GET    /names/validatecreate                 - validateNamesCreate(List<NameElementCommand>)
-           read      GET    /names/validateupdate                 - validateNamesUpdate(List<NameElementCommand>)
-           read      GET    /names/validatedelete                 - validateNamesDelete(List<NameElementCommand>)
+           read      GET    /names/validatecreate                 - validateNamesCreate          (List<NameElementCommand>)
+           read      GET    /names/validateupdate                 - validateNamesUpdate          (List<NameElementCommand>)
+           read      GET    /names/validatedelete                 - validateNamesDelete          (List<NameElementCommand>)
            ----------------------------------------------------------------------------------------------------
-           update    PUT    /names                                - updateNames(List<NameElementCommand>)
+           update    PUT    /names                                - updateNames                  (List<NameElementCommand>)
+           update    PUT    /names/upload                         - updateNames                  (MultipartFile)
            ----------------------------------------------------------------------------------------------------
-           delete    DELETE /names                                - deleteNames(List<NameElementCommand>)
+           delete    DELETE /names                                - deleteNames                  (List<NameElementCommand>)
+           delete    DELETE /names/upload                         - deleteNames                  (MultipartFile)
 
        Note
            read      GET    /names/{name} - both name and uuid (name - exact and search, uuid exact)
+           /upload and /download endpoints handle Excel files
      */
 
     public static final String DEFAULT_PAGE       = "0";
@@ -115,7 +124,7 @@ public interface INames {
 
     /**
      * Create names by list of name elements.
-     * Return list of created name elements.
+     * Return list of name elements for created names.
      *
      * @param nameElements list of name elements
      * @return list of created name elements
@@ -124,20 +133,24 @@ public interface INames {
             summary     = "Create names by array of name elements",
             description = """
                           Create names by array of name elements.
-                          Return array of created name elements.
+                          Return array of name elements for created names.
 
                           Required attributes:
-                          - parentsystemstructure
+                          - parentsystemstructure (uuid)
                           - description
                           - comment
 
+                          Optional attributes:
+                          - parentdevicestructure (uuid)
+                          - index
+
                           Uuid is created by Naming.
                           """
     )
     @ApiResponses(value = {
             @ApiResponse(
                     responseCode = "201",
-                    description  = "OK. Return array of created name elements.",
+                    description  = "OK. Return array of name elements for created names.",
                     content = @Content(
                             mediaType = "application/json",
                             array = @ArraySchema(schema = @Schema(implementation = NameElement.class)))),
@@ -176,6 +189,69 @@ public interface INames {
                                             requiredProperties = {"parentsystemstructure","parentdevicestructure","index","description","comment"}))))
             @RequestBody List<NameElementCommand> nameElements);
 
+    /**
+     * Create names by upload Excel file.
+     * Return Excel file with name elements for created names.
+     *
+     * @param file file
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Create names by upload Excel file",
+            description = """
+                          Create names by upload Excel file.
+                          Return Excel file with name elements for created names.
+
+                          Expected columns as in Excel template for names.
+
+                          Required attributes:
+                          - parentsystemstructure (uuid)
+                          - description
+                          - comment
+
+                          Optional attributes:
+                          - parentdevicestructure (uuid)
+                          - index
+
+                          Uuid is created by Naming.
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "201",
+                    description  = "OK. Return Excel file with name elements for created names.",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @PostMapping(
+            value = "/upload",
+            produces = {"application/vnd.ms-excel"},
+            consumes = {"multipart/form-data"})
+    public ResponseEntity<Resource> createNames(
+            @Parameter(
+                    in = ParameterIn.DEFAULT,
+                    description = "Excel file with name elements",
+                    required = true,
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_OPENXML_SPREADSHEET))
+            @RequestParam("file") MultipartFile file);
+
     // ----------------------------------------------------------------------------------------------------
 
     /**
@@ -236,6 +312,63 @@ public interface INames {
             @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
             @Parameter(in = ParameterIn.QUERY, description = "page size, limit") @RequestParam(required = false, defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize);
 
+    /**
+     * Find valid names (search).
+     * Return Excel file with paged list of name elements.
+     *
+     * @param deleted if deleted-only names are to be included
+     * (false for non-deleted-only names, true for deleted-only names, not used for both cases)
+     * @param queryFields search fields
+     * @param queryValues search values corresponding to search fields
+     * @param orderBy order by field
+     * @param isAsc sort order, ascending or descending
+     * @param page page starting from 0, offset
+     * @param pageSize page size, limit
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Find valid names (search) and download Excel file",
+            description = """
+                          Find valid names (search).
+                          Return Excel file with paged list of name elements.
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return Excel file with paged list of name elements.",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @GetMapping(
+            value = "/download",
+            produces = {"application/vnd.ms-excel"})
+    public ResponseEntity<Resource> readNamesDownload(
+            @Parameter(in = ParameterIn.QUERY, description = "if deleted names are to be included or not, omitted for both deleted and not deleted names") @RequestParam(required = false) Boolean deleted,
+            @Parameter(in = ParameterIn.QUERY, description = "search fields") @RequestParam(required = false) FieldName[] queryFields,
+            @Parameter(in = ParameterIn.QUERY, description = "search values corresponding to search fields") @RequestParam(required = false) String[] queryValues,
+            @Parameter(in = ParameterIn.QUERY, description = "order by field") @RequestParam(required = false) FieldName orderBy,
+            @Parameter(in = ParameterIn.QUERY, description = "sort order, ascending or descending") @RequestParam(required = false) Boolean isAsc,
+            @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
+            @Parameter(in = ParameterIn.QUERY, description = "page size, limit") @RequestParam(required = false, defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize);
+
     /**
      * Find valid names by name or uuid (search).
      * Return paged list of name elements.
@@ -663,7 +796,7 @@ public interface INames {
     // ----------------------------------------------------------------------------------------------------
 
     /**
-     * Return if name elements are valid to create.
+     * Return if names are valid to create by list of name elements.
      * If names are valid to create, successful create of names can be expected.
      *
      * <p>
@@ -672,25 +805,31 @@ public interface INames {
      * </p>
      *
      * @param nameElements list of name elements
-     * @return if list of name elements is valid to create
+     * @return if list of names is valid to create
      */
     @Hidden
     @Operation(
-            summary     = "Return if name elements are valid to create",
+            summary     = "Return if names are valid to create by list of name elements",
             description = """
-                          Return if name elements are valid to create.
+                          Return if names are valid to create by list of name elements.
                           If names are valid to create, successful create of names can be expected.
 
                           Required attributes:
-                          - parentsystemstructure
+                          - parentsystemstructure (uuid)
                           - description
                           - comment
+
+                          Optional attributes:
+                          - parentdevicestructure (uuid)
+                          - index
+
+                          Uuid is created by Naming.
                           """
     )
     @ApiResponses(value = {
             @ApiResponse(
                     responseCode = "200",
-                    description  = "OK. Response is true if all name elements validated ok, false otherwise. "
+                    description  = "OK. Response is true if all name elements validated ok, false otherwise."
                     + "Responses contain array with result for each name element. Message and details are available if no response is available.",
                     content = @Content(
                             mediaType = "application/json",
@@ -732,7 +871,7 @@ public interface INames {
             @RequestBody List<NameElementCommand> nameElements);
 
     /**
-     * Return if name elements are valid to update.
+     * Return if names are valid to update by list of name elements.
      * If names are valid to update, successful update of names can be expected.
      *
      * <p>
@@ -745,22 +884,26 @@ public interface INames {
      */
     @Hidden
     @Operation(
-            summary     = "Return if name elements are valid to update",
+            summary     = "Return if names are valid to update by list of name elements",
             description = """
-                          Return if name elements are valid to update.
+                          Return if names are valid to update by list of name elements.
                           If names are valid to update, successful update of names can be expected.
 
                           Required attributes:
                           - uuid
-                          - parentsystemstructure
+                          - parentsystemstructure (uuid)
                           - description
                           - comment
+
+                          Optional attributes:
+                          - parentdevicestructure (uuid)
+                          - index
                           """
     )
     @ApiResponses(value = {
             @ApiResponse(
                     responseCode = "200",
-                    description  = "OK. Response is true if all name elements validated ok, false otherwise. "
+                    description  = "OK. Response is true if all name elements validated ok, false otherwise."
                     + "Responses contain array with result for each name element. Message and details are available if no response is available.",
                     content = @Content(
                             mediaType = "application/json",
@@ -802,8 +945,8 @@ public interface INames {
             @RequestBody List<NameElementCommand> nameElements);
 
     /**
-     * Return if name elements are valid to delete.
-     * If names are valid to update, successful delete of names can be expected.
+     * Return if names are valid to delete by list of name elements.
+     * If names are valid to delete, successful delete of names can be expected.
      *
      * <p>
      * Response is true if all name elements validated ok, false otherwise, responses contain array
@@ -815,20 +958,22 @@ public interface INames {
      */
     @Hidden
     @Operation(
-            summary     = "Return if name elements are valid to delete",
+            summary     = "Return if names are valid to delete by list of name elements",
             description = """
-                          Return if name elements are valid to delete.
-                          If names are valid to update, successful delete of names can be expected.
+                          Return if names are valid to delete by list of name elements.
+                          If names are valid to delete, successful delete of names can be expected.
 
                           Required attributes:
                           - uuid
                           - comment
+
+                          Other attributes are not considered.
                           """
     )
     @ApiResponses(value = {
             @ApiResponse(
                     responseCode = "200",
-                    description  = "OK. Response is true if all name elements validated ok, false otherwise. "
+                    description  = "OK. Response is true if all name elements validated ok, false otherwise."
                     + "Responses contain array with result for each name element. Message and details are available if no response is available.",
                     content = @Content(
                             mediaType = "application/json",
@@ -873,30 +1018,32 @@ public interface INames {
 
     /**
      * Update names by list of name elements.
-     * Returns list of updated name elements.
+     * Return list of name elements for updated names.
      *
      * @param nameElements list of name elements
-     * @return list of updated name elements
+     * @return list of name elements for updated names
      */
     @Operation(
             summary     = "Update names by array of name elements",
             description = """
                           Update names by array of name elements.
-                          Return array of updated name elements.
+                          Return array of name elements for updated names.
 
                           Required attributes:
                           - uuid
-                          - parentsystemstructure
+                          - parentsystemstructure (uuid)
                           - description
                           - comment
 
-                          Other attributes are optional.
+                          Optional attributes:
+                          - parentdevicestructure (uuid)
+                          - index
                           """
     )
     @ApiResponses(value = {
             @ApiResponse(
                     responseCode = "200",
-                    description  = "OK. Return array of updated name elements.",
+                    description  = "OK. Return array of name elements for updated names.",
                     content = @Content(
                             mediaType = "application/json",
                             array = @ArraySchema(schema = @Schema(implementation = NameElement.class)))),
@@ -935,20 +1082,82 @@ public interface INames {
                                             requiredProperties = {"uuid","parentsystemstructure","description","comment"}))))
             @RequestBody List<NameElementCommand> nameElements);
 
+    /**
+     * Update names by upload Excel file.
+     * Return Excel file with name elements for updated names.
+     *
+     * @param file file
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Update names by upload Excel file",
+            description = """
+                          Update names by upload Excel file.
+                          Return Excel file with name elements for updated names.
+
+                          Expected columns as in Excel template for names.
+
+                          Required attributes:
+                          - uuid
+                          - parentsystemstructure (uuid)
+                          - description
+                          - comment
+
+                          Optional attributes:
+                          - parentdevicestructure (uuid)
+                          - index
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return Excel file with name elements for updated names.",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @PutMapping(
+            value = "/upload",
+               produces = {"application/vnd.ms-excel"},
+            consumes = {"multipart/form-data"})
+    public ResponseEntity<Resource> updateNames(
+            @Parameter(
+                    in = ParameterIn.DEFAULT,
+                    description = "Excel file with name elements",
+                    required = true,
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_OPENXML_SPREADSHEET))
+            @RequestParam("file") MultipartFile file);
+
     // ----------------------------------------------------------------------------------------------------
 
     /**
      * Delete names by list of name elements.
-     * Returns list of deleted name elements.
+     * Return list of name elements for deleted names.
      *
-     * @param uuid uuid
-     * @return list of deleted name elements
+     * @param nameElements list of name elements
+     * @return list of name elements for deleted names
      */
     @Operation(
             summary     = "Delete names by array of name elements",
             description = """
                           Delete names by array of name elements.
-                          Return array of deleted name elements.
+                          Return array of name elements for deleted names.
 
                           Required attributes:
                           - uuid
@@ -960,7 +1169,7 @@ public interface INames {
     @ApiResponses(value = {
             @ApiResponse(
                     responseCode = "200",
-                    description  = "OK. Return array of deleted name elements.",
+                    description  = "OK. Return array of name elements for deleted names.",
                     content = @Content(
                             mediaType = "application/json",
                             array = @ArraySchema(schema = @Schema(implementation = NameElement.class)))),
@@ -999,4 +1208,62 @@ public interface INames {
                                             requiredProperties = {"uuid","comment"}))))
             @RequestBody List<NameElementCommand> nameElements);
 
+    /**
+     * Delete names by upload Excel file.
+     * Return Excel file with name elements for deleted names.
+     *
+     * @param file file
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Delete names by upload Excel file",
+            description = """
+                          Delete names by upload Excel file.
+                          Return Excel file with name elements for deleted names.
+
+                          Expected columns as in Excel template for names.
+
+                          Required attributes:
+                          - uuid
+                          - comment
+
+                          Other attributes are not considered.
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return Excel file with name elements for deleted names.",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @DeleteMapping(
+            value = "/upload",
+            produces = {"application/vnd.ms-excel"},
+            consumes = {"multipart/form-data"})
+    public ResponseEntity<Resource> deleteNames(
+            @Parameter(
+                    in = ParameterIn.DEFAULT,
+                    description = "Excel file with name elements",
+                    required = true,
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_OPENXML_SPREADSHEET))
+            @RequestParam("file") MultipartFile file);
+
 }
diff --git a/src/main/java/org/openepics/names/rest/api/v1/IStructures.java b/src/main/java/org/openepics/names/rest/api/v1/IStructures.java
index 17cba1bb25bb8a260ee448ae8cadb7db734249d3..45d962ad63206959d7a94d7e82cf3ccae9f521d3 100644
--- a/src/main/java/org/openepics/names/rest/api/v1/IStructures.java
+++ b/src/main/java/org/openepics/names/rest/api/v1/IStructures.java
@@ -29,6 +29,8 @@ import org.openepics.names.rest.beans.response.Response;
 import org.openepics.names.rest.beans.response.ResponseBoolean;
 import org.openepics.names.rest.beans.response.ResponseBooleanList;
 import org.openepics.names.rest.beans.response.ResponsePageStructureElements;
+import org.openepics.names.util.ExcelUtil;
+import org.springframework.core.io.Resource;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -39,6 +41,7 @@ import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
 
 import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.Operation;
@@ -66,20 +69,23 @@ public interface IStructures {
        Status           - APPROVED, ARCHIVED, CANCELLED, PENDING, REJECTED
        FieldStructure   - UUID, PARENT, NAME, MNEMONIC, MNEMONICEQUIVALENCE, MNEMONICPATH, DESCRIPTION
 
-       StructureElement - type            (Type)
+       StructureElementCommand - subset of StructureElement attributes
+       StructureElement
                           uuid            (UUID)
+                          type            (Type)
                           parent          (UUID)
                           name            (String)
                           mnemonic        (String)
+                          description     (String)
+                          comment         (String)
+                          -------------------------
                           mnemonicpath    (String)
                           level           (Integer)
-                          description     (String)
                           status          (Status)
                           latest          (Boolean)
                           deleted         (Boolean)
                           when            (Date)
                           who             (String)
-                          comment         (String)
 
        authentication/authorization
            3 levels - no, user, administrator
@@ -91,8 +97,10 @@ public interface IStructures {
 
        Methods
            create    POST   /structures                                       - createStructures               (List<StructureElementCommand>)
+           create    POST   /structures/upload                                - createStructures               (MultipartFile)
            ----------------------------------------------------------------------------------------------------
            read      GET    /structures/{type}                                - readStructures                 (Type, Status[], Boolean, FieldStructure[], String[], FieldStructure, Boolean, Integer, Integer)
+           read      GET    /structures/{type}/download                       - readStructuresDownload         (Type, Status[], Boolean, FieldStructure[], String[], FieldStructure, Boolean, Integer, Integer)
            read      GET    /structures/children/{type}/{uuid}                - readStructuresChildren         (Type, String, FieldStructure, Boolean, Integer, Integer)
            read      GET    /structures/mnemonic/{mnemonic}                   - readStructuresMnemonic         (String, FieldStructure, Boolean, Integer, Integer, FieldStructure, Boolean, Integer, Integer)
            read      GET    /structures/mnemonicpath/{mnemonicpath}           - readStructuresMnemonicpath     (String, FieldStructure, Boolean, Integer, Integer, FieldStructure, Boolean, Integer, Integer)
@@ -110,12 +118,20 @@ public interface IStructures {
            read      GET    /structures/validatereject                        - validateStructuresReject       (List<StructureElementCommand>)
            ----------------------------------------------------------------------------------------------------
            update    PUT    /structures                                       - updateStructures               (List<StructureElementCommand>)
+           update    PUT    /structures/upload                                - updateStructures               (MultipartFile)
            ----------------------------------------------------------------------------------------------------
            delete    DELETE /structures                                       - deleteStructures               (List<StructureElementCommand>)
+           delete    DELETE /structures/upload                                - deleteStructures               (MultipartFile)
            ----------------------------------------------------------------------------------------------------
            update    PATCH  /structures/approve                               - approveStructures              (List<StructureElementCommand>)
+           update    PATCH  /structures/approve/upload                        - approveStructures              (MultipartFile)
            update    PATCH  /structures/cancel                                - cancelStructures               (List<StructureElementCommand>)
+           update    PATCH  /structures/cancel/upload                         - cancelStructures               (MultipartFile)
            update    PATCH  /structures/reject                                - rejectStructures               (List<StructureElementCommand>)
+           update    PATCH  /structures/reject/upload                         - rejectStructures               (MultipartFile)
+
+       Note
+           /upload and /download endpoints handle Excel files
      */
 
     public static final String DEFAULT_PAGE       = "0";
@@ -123,20 +139,7 @@ public interface IStructures {
 
     /**
      * Create (propose) structures by list of structure elements.
-     * Return list of created structure elements (proposals).
-     *
-     * <p>
-     * StructureElement attributes required:
-     * <ul>
-     * <li>type</li>
-     * <li>parent (System, Subsystem, DeviceGroup, DeviceType)</li>
-     * <li>name</li>
-     * <li>mnemonic (System, Subsystem, Discipline, DeviceType)
-     * (may be set for SystemGroup, not allowed for DeviceGroup)</li>
-     * <li>description</li>
-     * <li>comment</li>
-     * </ul>
-     * </p>
+     * Return list of structure elements for created structures (proposals).
      *
      * @param structureElements list of structure elements
      * @return list of structure elements for created structures (proposals)
@@ -145,11 +148,11 @@ public interface IStructures {
             summary     = "Create (propose) structures by array of structure elements",
             description = """
                           Create (propose) structures by array of structure elements.
-                          Return array of created structure elements (proposals).
+                          Return array of structure elements for created structures (proposals).
 
                           Required attributes:
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -206,6 +209,74 @@ public interface IStructures {
                                             requiredProperties = {"type","parent","name","mnemonic","description","comment"}))))
             @RequestBody List<StructureElementCommand> structureElements);
 
+    /**
+     * Create (propose) structures by upload Excel file.
+     * Return Excel file with structure elements for created structures (proposals).
+     *
+     * @param file file
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Create (propose) structures by upload Excel file",
+            description = """
+                          Create (propose) structures by upload Excel file.
+                          Return Excel file with structure elements for created structures (proposals).
+
+                          Expected columns as in Excel template for structures.
+
+                          Required attributes:
+                          - type
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
+                          - name
+                          - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
+                          - description
+                          - comment
+
+                          Uuid is created by Naming.
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "201",
+                    description  = "OK. Return Excel file with structure elements for created structures (proposals).",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "409",
+                    description  = "Conflict. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @PostMapping(
+            value = "/upload",
+            produces = {"application/vnd.ms-excel"},
+            consumes = {"multipart/form-data"})
+    public ResponseEntity<Resource> createStructures(
+            @Parameter(
+                    in = ParameterIn.DEFAULT,
+                    description = "Excel file with structure elements",
+                    required = true,
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_OPENXML_SPREADSHEET))
+            @RequestParam("file") MultipartFile file);
+
     // ----------------------------------------------------------------------------------------------------
 
     /**
@@ -271,6 +342,67 @@ public interface IStructures {
             @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
             @Parameter(in = ParameterIn.QUERY, description = "page size, limit") @RequestParam(required = false, defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize);
 
+    /**
+     * Find valid structures (search).
+     * Return Excel file with paged list of structure elements.
+     *
+     * @param type type of structure to search in
+     * @param statuses statuses of structures to search for
+     * @param deleted if deleted-only structures are to be included
+     * (false for non-deleted-only structures, true for deleted-only structures, not used for both cases)
+     * @param queryFields search fields
+     * @param queryValues search values corresponding to search fields
+     * @param orderBy order by field
+     * @param isAsc sort order, ascending or descending
+     * @param page page starting from 0, offset
+     * @param pageSize page size, limit
+     * @return paged list of structure elements
+     */
+    @Operation(
+            summary     = "Find valid structures (search) and download Excel file",
+            description = """
+                          Find valid structures (search).
+                          Return Excel file with paged list of structure elements.
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return Excel file with paged list of structure elements.",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @GetMapping(
+            value = "/{type}/download",
+            produces = {"application/vnd.ms-excel"})
+    public ResponseEntity<Resource> readStructuresDownload(
+            @Parameter(in = ParameterIn.PATH,  description = "type of structure to search in") @PathVariable("type") Type type,
+            @Parameter(in = ParameterIn.QUERY, description = "statuses of structures to search for") @RequestParam(required = false) Status[] statuses,
+            @Parameter(in = ParameterIn.QUERY, description = "if deleted structures are to be included or not, omitted for both deleted and not deleted structures") @RequestParam(required = false) Boolean deleted,
+            @Parameter(in = ParameterIn.QUERY, description = "search fields") @RequestParam(required = false) FieldStructure[] queryFields,
+            @Parameter(in = ParameterIn.QUERY, description = "search values corresponding to search fields") @RequestParam(required = false) String[] queryValues,
+            @Parameter(in = ParameterIn.QUERY, description = "order by field") @RequestParam(required = false) FieldStructure orderBy,
+            @Parameter(in = ParameterIn.QUERY, description = "sort order, ascending or descending") @RequestParam(required = false) Boolean isAsc,
+            @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
+            @Parameter(in = ParameterIn.QUERY, description = "page size, limit") @RequestParam(required = false, defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize);
+
     /**
      * Find valid children structures by type and parent uuid (exact match).
      * Return paged list of structure elements.
@@ -661,8 +793,8 @@ public interface IStructures {
     // ----------------------------------------------------------------------------------------------------
 
     /**
-     * Return if structure elements are valid to create (propose).
-     * If structure elements are valid to create, successful create of structures can be expected.
+     * Return if structures are valid to create (propose) by list of structure elements.
+     * If structures are valid to create, successful create of structures can be expected.
      *
      * <p>
      * Returned object has four fields (message, details, response, responses).
@@ -675,18 +807,18 @@ public interface IStructures {
      * </p>
      *
      * @param structureElements list of structure elements
-     * @return if list of structure elements is valid to create (propose)
+     * @return if list of structures is valid to create (propose)
      */
     @Hidden
     @Operation(
-            summary     = "Return if structure elements are valid to create (propose)",
+            summary     = "Return if structures are valid to create (propose) by list of structure elements",
             description = """
-                          Return if structure elements are valid to create (propose).
-                          If structure elements are valid to create, successful create of structures can be expected.
+                          Return if structures are valid to create (propose) by list of structure elements.
+                          If structures are valid to create, successful create of structures can be expected.
 
                           Required attributes:
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -744,8 +876,8 @@ public interface IStructures {
             @RequestBody List<StructureElementCommand> structureElements);
 
     /**
-     * Return if structure elements are valid to update (propose).
-     * If structure elements are valid to update, successful update of structures can be expected.
+     * Return if structures are valid to update (propose) by list of structure elements.
+     * If structures are valid to update, successful update of structures can be expected.
      *
      * <p>
      * Returned object has four fields (message, details, response, responses).
@@ -758,19 +890,19 @@ public interface IStructures {
      * </p>
      *
      * @param structureElements list of structure elements
-     * @return if list of structure elements is valid to update (propose)
+     * @return if list of structures is valid to update (propose)
      */
     @Hidden
     @Operation(
-            summary     = "Return if structure elements are valid to update (propose)",
+            summary     = "Return if structures are valid to update (propose) by list of structure elements",
             description = """
-                          Return if structure elements are valid to update (propose).
-                          If structure elements are valid to update, successful update of structures can be expected.
+                          Return if structures are valid to update (propose) by list of structure elements.
+                          If structures are valid to update, successful update of structures can be expected.
 
                           Required attributes:
                           - uuid
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -828,8 +960,8 @@ public interface IStructures {
             @RequestBody List<StructureElementCommand> structureElements);
 
     /**
-     * Return if structure elements are valid to delete (propose).
-     * If structure elements are valid to delete, successful delete of structures can be expected.
+     * Return if structures are valid to delete (propose) by list of structure elements.
+     * If structures are valid to delete, successful delete of structures can be expected.
      *
      * <p>
      * Returned object has four fields (message, details, response, responses).
@@ -842,14 +974,14 @@ public interface IStructures {
      * </p>
      *
      * @param structureElements list of structure elements
-     * @return if list of structure elements is valid to delete (propose)
+     * @return if list of structures is valid to delete (propose)
      */
     @Hidden
     @Operation(
-            summary     = "Return if structure elements are valid to delete (propose)",
+            summary     = "Return if structures are valid to delete (propose) by list of structure elements",
             description = """
-                          Return if structure elements are valid to delete (propose).
-                          If structure elements are valid to delete, successful delete of structures can be expected.
+                          Return if structures are valid to delete (propose) by list of structure elements.
+                          If structures are valid to delete, successful delete of structures can be expected.
 
                           Required attributes:
                           - uuid
@@ -908,8 +1040,8 @@ public interface IStructures {
             @RequestBody List<StructureElementCommand> structureElements);
 
     /**
-     * Return if structure elements are valid to approve.
-     * If structure elements are valid to approve, successful approve of structures can be expected.
+     * Return if structures are valid to approve by list of structure elements.
+     * If structures are valid to approve, successful approve of structures can be expected.
      *
      * <p>
      * Returned object has four fields (message, details, response, responses).
@@ -922,19 +1054,19 @@ public interface IStructures {
      * </p>
      *
      * @param structureElements list of structure elements
-     * @return if list of structure elements is valid to approve
+     * @return if list of structures is valid to approve
      */
     @Hidden
     @Operation(
-            summary     = "Return if structure elements are valid to approve",
+            summary     = "Return if structures are valid to approve by list of structure elements",
             description = """
-                          Return if structure elements are valid to approve.
-                          If structure elements are valid to approve, successful approve of structures can be expected.
+                          Return if structures are valid to approve by list of structure elements.
+                          If structures are valid to approve, successful approve of structures can be expected.
 
                           Required attributes:
                           - uuid
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -992,8 +1124,8 @@ public interface IStructures {
             @RequestBody List<StructureElementCommand> structureElements);
 
     /**
-     * Return if structure elements are valid to cancel.
-     * If structure elements are valid to cancel, successful cancel of structures can be expected.
+     * Return if structures are valid to cancel by list of structure elements.
+     * If structures are valid to cancel, successful cancel of structures can be expected.
      *
      * <p>
      * Returned object has four fields (message, details, response, responses).
@@ -1006,19 +1138,19 @@ public interface IStructures {
      * </p>
      *
      * @param structureElements list of structure elements
-     * @return if list of structure elements is valid to cancel
+     * @return if list of structures is valid to cancel
      */
     @Hidden
     @Operation(
-            summary     = "Return if structure elements are valid to cancel",
+            summary     = "Return if structures are valid to cancel by list of structure elements",
             description = """
-                          Return if structure elements are valid to cancel.
-                          If structure elements are valid to cancel, successful cancel of structures can be expected.
+                          Return if structures are valid to cancel by list of structure elements.
+                          If structures are valid to cancel, successful cancel of structures can be expected.
 
                           Required attributes:
                           - uuid
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -1076,8 +1208,8 @@ public interface IStructures {
             @RequestBody List<StructureElementCommand> structureElements);
 
     /**
-     * Return if structure elements are valid to reject.
-     * If structure elements are valid to reject, successful reject of structures can be expected.
+     * Return if structures are valid to reject by list of structure elements.
+     * If structures are valid to reject, successful reject of structures can be expected.
      *
      * <p>
      * Returned object has four fields (message, details, response, responses).
@@ -1090,19 +1222,19 @@ public interface IStructures {
      * </p>
      *
      * @param structureElements list of structure elements
-     * @return if list of structure elements is valid to reject
+     * @return if list of structures is valid to reject
      */
     @Hidden
     @Operation(
-            summary     = "Return if structure elements are valid to reject",
+            summary     = "Return if structures are valid to reject by list of structure elements",
             description = """
-                          Return if structure elements are valid to reject.
-                          If structure elements are valid to reject, successful reject of structures can be expected.
+                          Return if structures are valid to reject by list of structure elements.
+                          If structures are valid to reject, successful reject of structures can be expected.
 
                           Required attributes:
                           - uuid
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -1163,7 +1295,7 @@ public interface IStructures {
 
     /**
      * Update (propose) structures by list of structure elements.
-     * Return list of updated structure elements (proposals).
+     * Return list of structure elements for updated structures (proposals).
      *
      * @param structureElements list of structure elements
      * @return list of structure elements for updated structures (proposals)
@@ -1172,12 +1304,12 @@ public interface IStructures {
             summary     = "Update (propose) structures by array of structure elements",
             description = """
                           Update (propose) structures by array of structure elements.
-                          Return array of updated structure elements (proposals).
+                          Return array of structure elements for updated structures (proposals).
 
                           Required attributes:
                           - uuid
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -1232,11 +1364,78 @@ public interface IStructures {
                                             requiredProperties = {"uuid","type","parent","name","mnemonic","description","comment"}))))
             @RequestBody List<StructureElementCommand> structureElements);
 
+    /**
+     * Update (propose) structures by upload Excel file.
+     * Return Excel file with structure elements for updated structures (proposals).
+     *
+     * @param file file
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Update (propose) structures by upload Excel file",
+            description = """
+                          Update (propose) structures by upload Excel file.
+                          Return Excel file with structure elements for updated structures (proposals).
+
+                          Expected columns as in Excel template for structures.
+
+                          Required attributes:
+                          - uuid
+                          - type
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
+                          - name
+                          - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
+                          - description
+                          - comment
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return Excel file with structure elements for updated structures (proposals).",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "409",
+                    description  = "Conflict. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @PutMapping(
+            value = "/upload",
+            produces = {"application/vnd.ms-excel"},
+            consumes = {"multipart/form-data"})
+    public ResponseEntity<Resource> updateStructures(
+            @Parameter(
+                    in = ParameterIn.DEFAULT,
+                    description = "Excel file with structure elements",
+                    required = true,
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_OPENXML_SPREADSHEET))
+            @RequestParam("file") MultipartFile file);
+
     // ----------------------------------------------------------------------------------------------------
 
     /**
      * Delete (propose) structures by list of structure elements.
-     * Return list of deleted structure elements (proposals).
+     * Return list of structure elements for deleted structures (proposals).
      *
      * @param structureElements list of structure elements
      * @return list of structure elements for deleted structures (proposals)
@@ -1245,7 +1444,7 @@ public interface IStructures {
             summary     = "Delete (propose) structures by array of structure elements",
             description = """
                           Delete (propose) structures by array of structure elements.
-                          Return array of deleted structure elements (proposals).
+                          Return array of structure elements for deleted structures (proposals).
 
                           Required attributes:
                           - uuid
@@ -1303,12 +1502,75 @@ public interface IStructures {
                                             requiredProperties = {"uuid","type","comment"}))))
             @RequestBody List<StructureElementCommand> structureElements);
 
+    /**
+     * Delete (propose) structures by upload Excel file.
+     * Return Excel file with structure elements for deleted structures (proposals).
+     *
+     * @param file file
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Delete (propose) structures by upload Excel file",
+            description = """
+                          Delete (propose) structures by upload Excel file.
+                          Return Excel file with structure elements for deleted structures (proposals).
+
+                          Expected columns as in Excel template for structures.
 
+                          Required attributes:
+                          - uuid
+                          - type
+                          - comment
+
+                          Other attributes are not considered.
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return Excel file with structure elements for deleted structures (proposals).",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "409",
+                    description  = "Conflict. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @DeleteMapping(
+            value = "/upload",
+            produces = {"application/vnd.ms-excel"},
+            consumes = {"multipart/form-data"})
+    public ResponseEntity<Resource> deleteStructures(
+            @Parameter(
+                    in = ParameterIn.DEFAULT,
+                    description = "Excel file with structure elements",
+                    required = true,
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_OPENXML_SPREADSHEET))
+            @RequestParam("file") MultipartFile file);
     // ----------------------------------------------------------------------------------------------------
 
     /**
      * Approve structures (proposals) by list of structure elements.
-     * Return list of approved structure elements.
+     * Return list of structure elements for approved structures.
      *
      * @param structureElements list of structure elements
      * @return list of structure elements for approved structures
@@ -1317,12 +1579,12 @@ public interface IStructures {
             summary     = "Approve structures (proposals) by array of structure elements",
             description = """
                           Approve structures (proposals) by array of structure elements.
-                          Return array of approved structure elements.
+                          Return array of structure elements for approved structures.
 
                           Required attributes:
                           - uuid
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -1378,6 +1640,73 @@ public interface IStructures {
                                             requiredProperties = {"uuid","type","parent","name","mnemonic","description","comment"}))))
             @RequestBody List<StructureElementCommand> structureElements);
 
+    /**
+     * Approve structures (proposals) by upload Excel file.
+     * Return Excel file with structure elements for approved structures.
+     *
+     * @param structureElements list of structure elements
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Approve structures (proposals) by upload Excel file",
+            description = """
+                          Approve structures (proposals) by upload Excel file.
+                          Return Excel file with structure elements for for approved structures.
+
+                          Expected columns as in Excel template for structures.
+
+                          Required attributes:
+                          - uuid
+                          - type
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
+                          - name
+                          - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
+                          - description
+                          - comment
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return Excel file with structure elements for approved structures.",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "409",
+                    description  = "Conflict. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @PatchMapping(
+            value = "/approve/upload",
+            produces = {"application/vnd.ms-excel"},
+            consumes = {"multipart/form-data"})
+    public ResponseEntity<Resource> approveStructures(
+            @Parameter(
+                    in = ParameterIn.DEFAULT,
+                    description = "Excel file with structure elements",
+                    required = true,
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_OPENXML_SPREADSHEET))
+            @RequestParam("file") MultipartFile file);
+
     /**
      * Cancel structures (proposals) by list of structure elements.
      * Return list of cancelled structure elements.
@@ -1389,12 +1718,12 @@ public interface IStructures {
             summary     = "Cancel structures (proposals) by array of structure elements",
             description = """
                           Cancel structures (proposals) by array of structure elements.
-                          Return array of cancelled structure elements.
+                          Return array of structure elements for cancelled structures.
 
                           Required attributes:
                           - uuid
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -1450,6 +1779,73 @@ public interface IStructures {
                                             requiredProperties = {"uuid","type","parent","name","mnemonic","description","comment"}))))
             @RequestBody List<StructureElementCommand> structureElements);
 
+    /**
+     * Cancel structures (proposals) by upload Excel file.
+     * Return Excel file with cancelled structure elements.
+     *
+     * @param structureElements list of structure elements
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Cancel structures (proposals) by upload Excel file",
+            description = """
+                          Cancel structures (proposals) by upload Excel file.
+                          Return Excel file with structure elements for cancelled structures.
+
+                          Expected columns as in Excel template for structures.
+
+                          Required attributes:
+                          - uuid
+                          - type
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
+                          - name
+                          - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
+                          - description
+                          - comment
+                          """
+)
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return Excel file with structure elements for cancelled structures.",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "409",
+                    description  = "Conflict. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @PatchMapping(
+            value = "/cancel/upload",
+            produces = {"application/vnd.ms-excel"},
+            consumes = {"multipart/form-data"})
+    public ResponseEntity<Resource> cancelStructures(
+            @Parameter(
+                    in = ParameterIn.DEFAULT,
+                    description = "Excel file with structure elements",
+                    required = true,
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_OPENXML_SPREADSHEET))
+            @RequestParam("file") MultipartFile file);
+
     /**
      * Reject structures (proposals) by list of structure elements.
      * Return list of rejected structure elements.
@@ -1461,12 +1857,12 @@ public interface IStructures {
             summary     = "Reject structures (proposals) by array of structure elements",
             description = """
                           Reject structures (proposals) by array of structure elements.
-                          Return array of rejected structure elements.
+                          Return array of structure elements for rejected structures.
 
                           Required attributes:
                           - uuid
                           - type
-                          - parent (System, Subsystem, DeviceGroup, DeviceType)
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
                           - name
                           - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
                           - description
@@ -1522,4 +1918,71 @@ public interface IStructures {
                                             requiredProperties = {"uuid","type","parent","name","mnemonic","description","comment"}))))
             @RequestBody List<StructureElementCommand> structureElements);
 
+    /**
+     * Reject structures (proposals) by upload Excel file.
+     * Return Excel file with rejected structure elements.
+     *
+     * @param structureElements list of structure elements
+     * @return Excel file
+     */
+    @Operation(
+            summary     = "Reject structures (proposals) by upload Excel file",
+            description = """
+                          Reject structures (proposals) by upload Excel file.
+                          Return Excel file with structure elements for rejected structures.
+
+                          Expected columns as in Excel template for structures.
+
+                          Required attributes:
+                          - uuid
+                          - type
+                          - parent (System, Subsystem, DeviceGroup, DeviceType)(uuid)
+                          - name
+                          - mnemonic (System, Subsystem, Discipline, DeviceType, may be set for SystemGroup, not allowed for DeviceGroup)
+                          - description
+                          - comment
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return Excel file with structure elements for rejected structures.",
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_EXCEL)),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "409",
+                    description  = "Conflict. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @PatchMapping(
+            value = "/reject/upload",
+            produces = {"application/vnd.ms-excel"},
+            consumes = {"multipart/form-data"})
+    public ResponseEntity<Resource> rejectStructures(
+            @Parameter(
+                    in = ParameterIn.DEFAULT,
+                    description = "Excel file with structure elements",
+                    required = true,
+                    content = @Content(mediaType = ExcelUtil.MIME_TYPE_OPENXML_SPREADSHEET))
+            @RequestParam("file") MultipartFile file);
+
 }
diff --git a/src/main/java/org/openepics/names/rest/beans/element/NameElement.java b/src/main/java/org/openepics/names/rest/beans/element/NameElement.java
index e3d1cf62bb43608f040d70a40a43abcdfef5af53..f0e1378df9e798925403a92ee3efc3d3eb1471f6 100644
--- a/src/main/java/org/openepics/names/rest/beans/element/NameElement.java
+++ b/src/main/java/org/openepics/names/rest/beans/element/NameElement.java
@@ -45,17 +45,17 @@ public class NameElement extends NameElementCommand implements Serializable {
     private String systemstructure;
     @Schema(description = "Mnemonic path for for the device structure.")
     private String devicestructure;
-    @Schema(description = "Name (verbose) of the name.")
+    @Schema(description = "Name (verbose) of the name entry.")
     private String name;
-    @Schema(description = "Status of the name.")
+    @Schema(description = "Status of the name entry.")
     private Status status;
-    @Schema(description = "If the name is latest (with status APPROVED) in its line of entries.")
+    @Schema(description = "If the name entry is latest (with status APPROVED) in its line of entries.")
     private Boolean latest;
-    @Schema(description = "If the name is deleted.")
+    @Schema(description = "If the name entry is deleted.")
     private Boolean deleted;
-    @Schema(description = "Date and time when the name was created.")
+    @Schema(description = "Date and time when the name entry was created.")
     private Date when;
-    @Schema(description = "(User) Name of who created the name.")
+    @Schema(description = "Name (user) of who created the name entry.")
     private String who;
 
     /**
diff --git a/src/main/java/org/openepics/names/rest/beans/element/NameElementCommand.java b/src/main/java/org/openepics/names/rest/beans/element/NameElementCommand.java
index b1899d42a8cfb5723cd7d6e7d212ad3b4f6573a6..2f21e63d3d394b5b8d4dc6e0bf938d57aa1dd184 100644
--- a/src/main/java/org/openepics/names/rest/beans/element/NameElementCommand.java
+++ b/src/main/java/org/openepics/names/rest/beans/element/NameElementCommand.java
@@ -38,17 +38,17 @@ public class NameElementCommand implements Serializable {
      */
     private static final long serialVersionUID = -3166840982436164399L;
 
-    @Schema(description = "Identity of the name. Value is set server-side.")
+    @Schema(description = "Identity (uuid) of the name entry. Value is created server-side.")
     private UUID uuid;
-    @Schema(description = "Identity for the system structure parent.")
+    @Schema(description = "Identity (uuid) for the system structure parent.")
     private UUID parentsystemstructure;
-    @Schema(description = "Identity for the device structure parent.")
+    @Schema(description = "Identity (uuid) for the device structure parent (if the name entry refers to device structure).")
     private UUID parentdevicestructure;
-    @Schema(description = "Index (instance) of the name.")
+    @Schema(description = "Index (instance) of the name entry (if the name entry refers to device structure).")
     private String index;
-    @Schema(description = "Description of the name.")
+    @Schema(description = "Description of the name entry.")
     private String description;
-    @Schema(description = "Comment of the name command.")
+    @Schema(description = "Comment of the name entry command.")
     private String comment;
 
     /**
diff --git a/src/main/java/org/openepics/names/rest/beans/element/StructureElement.java b/src/main/java/org/openepics/names/rest/beans/element/StructureElement.java
index 68f76cc3e8ead2cd1f2db51c1737aa61ba734251..30d5f1385e644b7565fa789a5eccdc6eed129b24 100644
--- a/src/main/java/org/openepics/names/rest/beans/element/StructureElement.java
+++ b/src/main/java/org/openepics/names/rest/beans/element/StructureElement.java
@@ -54,7 +54,7 @@ public class StructureElement extends StructureElementCommand implements Seriali
     private Boolean deleted;
     @Schema(description = "Date and time when the structure entry was created.")
     private Date when;
-    @Schema(description = "(User) Name of who created the structure entry.")
+    @Schema(description = "Name (user) of who created the structure entry.")
     private String who;
 
     /**
diff --git a/src/main/java/org/openepics/names/rest/beans/element/StructureElementCommand.java b/src/main/java/org/openepics/names/rest/beans/element/StructureElementCommand.java
index d64eaee01f1eea6f6ddf25be336e373e0768a05e..13b7ad80e5df7c913d89e7d18c59b2a6a0e682c4 100644
--- a/src/main/java/org/openepics/names/rest/beans/element/StructureElementCommand.java
+++ b/src/main/java/org/openepics/names/rest/beans/element/StructureElementCommand.java
@@ -41,11 +41,11 @@ public class StructureElementCommand implements Serializable {
      */
     private static final long serialVersionUID = 788979309267676232L;
 
-    @Schema(description = "Identity of the structure entry. Value is set server-side.")
+    @Schema(description = "Identity (uuid) of the structure entry. Value is created server-side.")
     private UUID uuid;
     @Schema(description = "Type of the structure entry.")
     private Type type;
-    @Schema(description = "Identity for the structure entry parent (if the structure entry has a parent).")
+    @Schema(description = "Identity (uuid) for the structure entry parent (if the structure entry has a parent).")
     private UUID parent;
     @Schema(description = "Name of the structure entry.")
     private String name;
diff --git a/src/main/java/org/openepics/names/rest/controller/NamesController.java b/src/main/java/org/openepics/names/rest/controller/NamesController.java
index 5ee006d6d783925a1bf6d979383dabef25177e81..5358b5d9dfbe8d09dc095478e3a6b7ce82bef03e 100644
--- a/src/main/java/org/openepics/names/rest/controller/NamesController.java
+++ b/src/main/java/org/openepics/names/rest/controller/NamesController.java
@@ -18,6 +18,7 @@
 
 package org.openepics.names.rest.controller;
 
+import java.io.IOException;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -32,13 +33,19 @@ import org.openepics.names.rest.beans.response.ResponseBooleanList;
 import org.openepics.names.rest.beans.response.ResponsePageNameElements;
 import org.openepics.names.service.NamesService;
 import org.openepics.names.service.exception.ServiceException;
+import org.openepics.names.util.ExcelUtil;
 import org.openepics.names.util.LogUtil;
 import org.openepics.names.util.TextUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import com.google.common.collect.Lists;
 
@@ -85,6 +92,41 @@ public class NamesController implements INames {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> createNames(MultipartFile file) {
+        // validate authority
+        //     naming user & admin
+        // validate
+        // do
+
+        try {
+             if (ExcelUtil.hasExcelFormat(file)) {
+                 List<NameElementCommand> nameElementCommands = ExcelUtil.excelToNameElementCommands(file.getInputStream());
+                 namesService.validateNamesCreate(nameElementCommands);
+                 List<NameElement> nameElements = namesService.createNames(nameElementCommands);
+                 InputStreamResource isr = new InputStreamResource(ExcelUtil.nameElementsToExcel(nameElements));
+                 return ResponseEntity.ok()
+                         .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=NameElement.xlsx")
+                         .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                         .body(isr);
+             } else {
+                 throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
+             }
+        } catch (ServiceException e) {
+            LogUtil.logServiceException(LOGGER, Level.SEVERE, e);
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        } catch (IOException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
+        } catch (Exception e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        }
+    }
+
     // ----------------------------------------------------------------------------------------------------
 
     @Override
@@ -106,6 +148,17 @@ public class NamesController implements INames {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> readNamesDownload(Boolean deleted, FieldName[] queryFields, String[] queryValues,
+            FieldName orderBy, Boolean isAsc, Integer page, Integer pageSize) {
+        ResponsePageNameElements nameElements = readNames(deleted, queryFields, queryValues, orderBy, isAsc, page, pageSize);
+        InputStreamResource isr = new InputStreamResource(ExcelUtil.nameElementsToExcel(nameElements));
+        return ResponseEntity.ok()
+                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=NameElement.xlsx")
+                .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                .body(isr);
+    }
+
     @Override
     public ResponsePageNameElements readNames(
             String name,
@@ -351,6 +404,41 @@ public class NamesController implements INames {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> updateNames(MultipartFile file) {
+        // validate authority
+        //     naming user & admin
+        // validate
+        // do
+
+        try {
+            if (ExcelUtil.hasExcelFormat(file)) {
+                List<NameElementCommand> nameElementCommands = ExcelUtil.excelToNameElementCommands(file.getInputStream());
+                namesService.validateNamesUpdate(nameElementCommands);
+                List<NameElement> nameElements = namesService.updateNames(nameElementCommands);
+                InputStreamResource isr = new InputStreamResource(ExcelUtil.nameElementsToExcel(nameElements));
+                return ResponseEntity.ok()
+                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=NameElement.xlsx")
+                        .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                        .body(isr);
+            } else {
+                throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
+            }
+       } catch (ServiceException e) {
+           LogUtil.logServiceException(LOGGER, Level.SEVERE, e);
+           LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+           throw e;
+       } catch (IOException e) {
+           LOGGER.log(Level.SEVERE, e.getMessage());
+           LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+           throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
+       } catch (Exception e) {
+           LOGGER.log(Level.SEVERE, e.getMessage());
+           LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+           throw e;
+       }
+    }
+
     // ----------------------------------------------------------------------------------------------------
 
     @Override
@@ -374,4 +462,39 @@ public class NamesController implements INames {
         }
     }
 
-}
\ No newline at end of file
+    @Override
+    public ResponseEntity<Resource> deleteNames(MultipartFile file) {
+        // validate authority
+        //     naming user & admin
+        // validate
+        // do
+
+        try {
+            if (ExcelUtil.hasExcelFormat(file)) {
+                List<NameElementCommand> nameElementCommands = ExcelUtil.excelToNameElementCommands(file.getInputStream());
+                namesService.validateNamesDelete(nameElementCommands);
+                List<NameElement> nameElements = namesService.deleteNames(nameElementCommands);
+                InputStreamResource isr = new InputStreamResource(ExcelUtil.nameElementsToExcel(nameElements));
+                return ResponseEntity.ok()
+                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=NameElement.xlsx")
+                        .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                        .body(isr);
+            } else {
+                throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
+            }
+        } catch (ServiceException e) {
+            LogUtil.logServiceException(LOGGER, Level.SEVERE, e);
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        } catch (IOException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
+        } catch (Exception e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        }
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/rest/controller/StructuresController.java b/src/main/java/org/openepics/names/rest/controller/StructuresController.java
index 9b708cb5a3b027c3c61ceb0591ae42bb08f2a77e..047ec6ca33d9a220caf7c9a4950dfa8b66f287ef 100644
--- a/src/main/java/org/openepics/names/rest/controller/StructuresController.java
+++ b/src/main/java/org/openepics/names/rest/controller/StructuresController.java
@@ -18,6 +18,7 @@
 
 package org.openepics.names.rest.controller;
 
+import java.io.IOException;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -34,13 +35,19 @@ import org.openepics.names.rest.beans.response.ResponseBooleanList;
 import org.openepics.names.rest.beans.response.ResponsePageStructureElements;
 import org.openepics.names.service.StructuresService;
 import org.openepics.names.service.exception.ServiceException;
+import org.openepics.names.util.ExcelUtil;
 import org.openepics.names.util.LogUtil;
 import org.openepics.names.util.TextUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import com.google.common.collect.Lists;
 
@@ -94,6 +101,41 @@ public class StructuresController implements IStructures {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> createStructures(MultipartFile file) {
+        // validate authority
+        //     naming user & admin
+        // validate
+        // do
+
+        try {
+            if (ExcelUtil.hasExcelFormat(file)) {
+                List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
+                structuresService.validateStructuresCreate(structureElementCommands);
+                List<StructureElement> structureElements = structuresService.createStructures(structureElementCommands);
+                InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
+                return ResponseEntity.ok()
+                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=StructureElement.xlsx")
+                        .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                        .body(isr);
+            } else {
+                throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
+            }
+       } catch (ServiceException e) {
+           LogUtil.logServiceException(LOGGER, Level.SEVERE, e);
+           LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+           throw e;
+       } catch (IOException e) {
+           LOGGER.log(Level.SEVERE, e.getMessage());
+           LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+           throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
+       } catch (Exception e) {
+           LOGGER.log(Level.SEVERE, e.getMessage());
+           LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+           throw e;
+       }
+    }
+
     // ----------------------------------------------------------------------------------------------------
 
     @Override
@@ -115,6 +157,18 @@ public class StructuresController implements IStructures {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> readStructuresDownload(Type type, Status[] statuses, Boolean deleted,
+            FieldStructure[] queryFields, String[] queryValues, FieldStructure orderBy, Boolean isAsc, Integer page,
+            Integer pageSize) {
+        ResponsePageStructureElements structureElements = readStructures(type, statuses, deleted, queryFields, queryValues, orderBy, isAsc, page, pageSize);
+        InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
+        return ResponseEntity.ok()
+                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=StructureElement.xlsx")
+                .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                .body(isr);
+    }
+
     @Override
     public ResponsePageStructureElements readStructuresChildren(
             Type type, String uuid,
@@ -434,6 +488,35 @@ public class StructuresController implements IStructures {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> updateStructures(MultipartFile file) {
+        try {
+            if (ExcelUtil.hasExcelFormat(file)) {
+                List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
+                structuresService.validateStructuresUpdate(structureElementCommands);
+                List<StructureElement> structureElements = structuresService.updateStructures(structureElementCommands);
+                InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
+                return ResponseEntity.ok()
+                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=StructureElement.xlsx")
+                        .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                        .body(isr);
+            } else {
+                throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
+            }
+       } catch (ServiceException e) {
+           LogUtil.logServiceException(LOGGER, Level.SEVERE, e);
+           LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+           throw e;
+       } catch (IOException e) {
+           LOGGER.log(Level.SEVERE, e.getMessage());
+           LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+           throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
+       } catch (Exception e) {
+           LOGGER.log(Level.SEVERE, e.getMessage());
+           LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+           throw e;
+       }
+    }
 
     // ----------------------------------------------------------------------------------------------------
 
@@ -453,6 +536,36 @@ public class StructuresController implements IStructures {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> deleteStructures(MultipartFile file) {
+        try {
+            if (ExcelUtil.hasExcelFormat(file)) {
+                List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
+                structuresService.validateStructuresDelete(structureElementCommands);
+                List<StructureElement> structureElements = structuresService.deleteStructures(structureElementCommands);
+                InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
+                return ResponseEntity.ok()
+                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=StructureElement.xlsx")
+                        .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                        .body(isr);
+            } else {
+                throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
+            }
+        } catch (ServiceException e) {
+            LogUtil.logServiceException(LOGGER, Level.SEVERE, e);
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        } catch (IOException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
+        } catch (Exception e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        }
+    }
+
     // ----------------------------------------------------------------------------------------------------
 
     @Override
@@ -471,6 +584,36 @@ public class StructuresController implements IStructures {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> approveStructures(MultipartFile file) {
+        try {
+            if (ExcelUtil.hasExcelFormat(file)) {
+                List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
+                structuresService.validateStructuresApprove(structureElementCommands);
+                List<StructureElement> structureElements = structuresService.approveStructures(structureElementCommands);
+                InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
+                return ResponseEntity.ok()
+                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=StructureElement.xlsx")
+                        .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                        .body(isr);
+            } else {
+                throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
+            }
+        } catch (ServiceException e) {
+            LogUtil.logServiceException(LOGGER, Level.SEVERE, e);
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        } catch (IOException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
+        } catch (Exception e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        }
+    }
+
     @Override
     public List<StructureElement> cancelStructures(List<StructureElementCommand> structureElements) {
         try {
@@ -487,6 +630,36 @@ public class StructuresController implements IStructures {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> cancelStructures(MultipartFile file) {
+        try {
+            if (ExcelUtil.hasExcelFormat(file)) {
+                List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
+                structuresService.validateStructuresCancel(structureElementCommands);
+                List<StructureElement> structureElements = structuresService.cancelStructures(structureElementCommands);
+                InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
+                return ResponseEntity.ok()
+                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=StructureElement.xlsx")
+                        .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                        .body(isr);
+            } else {
+                throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
+            }
+        } catch (ServiceException e) {
+            LogUtil.logServiceException(LOGGER, Level.SEVERE, e);
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        } catch (IOException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
+        } catch (Exception e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        }
+    }
+
     @Override
     public List<StructureElement> rejectStructures(List<StructureElementCommand> structureElements) {
         try {
@@ -503,4 +676,34 @@ public class StructuresController implements IStructures {
         }
     }
 
+    @Override
+    public ResponseEntity<Resource> rejectStructures(MultipartFile file) {
+        try {
+            if (ExcelUtil.hasExcelFormat(file)) {
+                List<StructureElementCommand> structureElementCommands = ExcelUtil.excelToStructureElementCommands(file.getInputStream());
+                structuresService.validateStructuresReject(structureElementCommands);
+                List<StructureElement> structureElements = structuresService.rejectStructures(structureElementCommands);
+                InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
+                return ResponseEntity.ok()
+                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=StructureElement.xlsx")
+                        .contentType(MediaType.parseMediaType(ExcelUtil.MIME_TYPE_EXCEL))
+                        .body(isr);
+            } else {
+                throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, null, null, null);
+            }
+        } catch (ServiceException e) {
+            LogUtil.logServiceException(LOGGER, Level.SEVERE, e);
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        } catch (IOException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw new ServiceException(TextUtil.FILE_COULD_NOT_BE_PARSED, e.getMessage(), null, e);
+        } catch (Exception e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+            LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e);
+            throw e;
+        }
+    }
+
 }
diff --git a/src/main/java/org/openepics/names/util/ExcelUtil.java b/src/main/java/org/openepics/names/util/ExcelUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..b98389c8b08584d2cb0ca79ef877a52c1b202dba
--- /dev/null
+++ b/src/main/java/org/openepics/names/util/ExcelUtil.java
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2022 European Spallation Source ERIC.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+package org.openepics.names.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.ClientAnchor;
+import org.apache.poi.ss.usermodel.Comment;
+import org.apache.poi.ss.usermodel.CreationHelper;
+import org.apache.poi.ss.usermodel.DataFormat;
+import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.RichTextString;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.openepics.names.rest.beans.Type;
+import org.openepics.names.rest.beans.element.NameElement;
+import org.openepics.names.rest.beans.element.NameElementCommand;
+import org.openepics.names.rest.beans.element.StructureElement;
+import org.openepics.names.rest.beans.element.StructureElementCommand;
+import org.openepics.names.rest.beans.response.ResponsePageNameElements;
+import org.openepics.names.rest.beans.response.ResponsePageStructureElements;
+import org.openepics.names.service.exception.ServiceException;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Utility class to assist in handling of Excel files.
+ *
+ * @author Lars Johansson
+ */
+public class ExcelUtil {
+
+    private static final Logger LOGGER = Logger.getLogger(ExcelUtil.class.getName());
+
+    public static final String     MIME_TYPE_EXCEL                 = "application/vnd.ms-excel";
+    public static final String     MIME_TYPE_OPENXML_SPREADSHEET   = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+
+    // width (in units of 1/256th of a character width)
+    // column width 2.75 inch (to fit header text and uuid)
+    public static final int        SHEET_COLUMN_WIDTH              = 28 * 256 + 64;
+
+    public static final int        NAMEELEMENTCOMMAND_LENGTH       = 6;
+    public static final String[][] NAMEELEMENT_HEADER_COMMENT      = {
+            {"Uuid",                  "Identity (uuid) of the name entry. Value is created server-side."},
+            {"Parentsystemstructure", "Identity (uuid) for the system structure parent."},
+            {"Parentdevicestructure", "Identity (uuid) for the device structure parent (if the name entry refers to device structure)."},
+            {"Index",                 "Index (instance) of the name entry (if the name entry refers to device structure)."},
+            {"Description",           "Description of the name entry."},
+            {"Comment",               "Comment of the name entry command."},
+            // above NameElementCommand
+            {"Systemstructure",       "Mnemonic path for for the system structure."},
+            {"Devicestructure",       "Mnemonic path for for the device structure."},
+            {"Name",                  "Name (verbose) of the name entry."},
+            {"Status",                "Status of the name entry."},
+            {"Latest",                "If the name entry is latest (with status APPROVED) in its line of entries."},
+            {"Deleted",               "If the name entry is deleted."},
+            {"When",                  "Date and time when the name entry was created."},
+            {"Who",                   "Name (user) of who created the name entry."} };
+
+    public static final int        STRUCTUREELEMENTCOMMAND_LENGTH  = 7;
+    public static final String[][] STRUCTUREELEMENT_HEADER_COMMENT = {
+            {"Uuid",                  "Identity (uuid) of the structure entry. Value is created server-side."},
+            {"Type",                  "Type of the structure entry."},
+            {"Parent",                "Identity (uuid) for the structure entry parent (if the structure entry has a parent)."},
+            {"Name",                  "Name (verbose) of the structure entry."},
+            {"Mnemonic",              "Mnemonic of the structure entry."},
+            {"Description",           "Description of the structure entry."},
+            {"Comment",               "Comment of the structure entry command."},
+            // above StructureElementCommand
+            {"Mnemonicpath",          "Mnemonic path of the structure entry."},
+            {"Level",                 "Level of the structure entry."},
+            {"Status",                "Status of the structure entry."},
+            {"Latest",                "If the structure entry is latest (with status APPROVED) in its line of entries."},
+            {"Deleted",               "If the structure entry is deleted."},
+            {"When",                  "Date and time when the structure entry was created."},
+            {"Who",                   "Name (user) of who created the structure entry."} };
+
+    private static final String SHEET = "Entries";
+
+    private static final String ENTRIES_EXCEL_TO_NAME_ELEMENT_COMMANDS         = "excelToNameElementCommands, # entries: {0}";
+    private static final String ENTRIES_EXCEL_TO_STRUCTURE_ELEMENT_COMMANDS    = "excelToStructureElementCommands, # entries: {0}";
+    private static final String ENTRIES_NAME_ELEMENTS_TO_EXCEL                 = "nameElementsToExcel, # entries: {0}";
+    private static final String ENTRIES_STRUCTURE_ELEMENTS_TO_EXCEL            = "structureElementsToExcel, # entries: {0}";
+
+    private static final String FAILED_TO_EXPORT_VALUES_TO_FILE                = "Failed to export values to file";
+    private static final String FILE_COULD_NOT_BE_PARSED_FOR_VALUE_AT_ROW_CELL = "File could not be parsed for value at row: {0} cell: {1}";
+    private static final String INVALID_SHEET_EXPECTED_SHEET                   = "Invalid sheet. Expected sheet: {0}";
+    private static final String INVALID_VALUE_EXPECTED_VALUE                   = "Invalid value: {0} Expected value: {1}";
+    private static final String INVALID_VALUE_UNEXPECTED_VALUE                 = "Invalid value: {0} Unexpected value.";
+
+    /**
+     * This class is not to be instantiated.
+     */
+    private ExcelUtil() {
+        throw new IllegalStateException("Utility class");
+    }
+
+    /**
+     * Utility method to check if file has Excel format.
+     *
+     * @param file file
+     * @return boolean if file has Excel format
+     */
+    public static boolean hasExcelFormat(MultipartFile file) {
+        return MIME_TYPE_OPENXML_SPREADSHEET.equals(file.getContentType());
+    }
+
+    /**
+     * Utility method to convert an Excel file to a list of name elements.
+     *
+     * @param is input stream
+     * @return list of name elements
+     */
+    public static List<NameElementCommand> excelToNameElementCommands(InputStream is) {
+        // rules for conversion
+        //     Excel as NameElementCommand accepted
+        //     Excel as NameElement not accepted
+        //     see validateHeaderNameElementCommand
+
+        int rowIndex = 0;
+        int columnIndex = 0;
+
+        try {
+              Workbook workbook = new XSSFWorkbook(is);
+              validateSheet(workbook);
+
+              Sheet sheet = workbook.getSheet(SHEET);
+              Iterator<Row> rows = sheet.iterator();
+              List<NameElementCommand> list = Lists.newArrayList();
+
+              // iterate over rows and columns (cells)
+              while (rows.hasNext()) {
+                  Row row = rows.next();
+                  Iterator<Cell> cells = row.iterator();
+                  NameElementCommand nameElementCommand = new NameElementCommand();
+
+                  while (cells.hasNext()) {
+                      Cell cell = cells.next();
+                      rowIndex = cell.getRowIndex();
+                      columnIndex = cell.getColumnIndex();
+
+                      // ensure header row with syntax
+                      if (rowIndex == 0) {
+                          validateHeaderNameElementCommand(cell);
+                          continue;
+                      }
+
+                      String value = cell.getStringCellValue();
+                      switch (columnIndex) {
+                      case 0:
+                          nameElementCommand.setUuid(!StringUtils.isEmpty(value) ? UUID.fromString(value) : null);
+                          break;
+                      case 1:
+                          nameElementCommand.setParentsystemstructure(!StringUtils.isEmpty(value) ? UUID.fromString(value) : null);
+                          break;
+                      case 2:
+                          nameElementCommand.setParentdevicestructure(!StringUtils.isEmpty(value) ? UUID.fromString(value) : null);
+                          break;
+                      case 3:
+                          nameElementCommand.setIndex(value);
+                          break;
+                      case 4:
+                          nameElementCommand.setDescription(value);
+                          break;
+                      case 5:
+                          nameElementCommand.setComment(value);
+                          break;
+                      default:
+                          throw new IllegalArgumentException(
+                                  MessageFormat.format(INVALID_VALUE_UNEXPECTED_VALUE, value));
+                      }
+                  }
+                  // not add header row
+                  if (rowIndex > 0) {
+                      list.add(nameElementCommand);
+                  }
+              }
+
+              workbook.close();
+              LOGGER.log(Level.INFO, ENTRIES_EXCEL_TO_NAME_ELEMENT_COMMANDS, list.size());
+              return list;
+        } catch (IllegalArgumentException | IOException e) {
+            throw new ServiceException(
+                    MessageFormat.format(FILE_COULD_NOT_BE_PARSED_FOR_VALUE_AT_ROW_CELL, rowIndex, columnIndex),
+                    e.getMessage(), null, e);
+        }
+    }
+
+    /**
+     * Utility method to convert an Excel file to a list of structure elements.
+     *
+     * @param is input stream
+     * @return list of structure elements
+     */
+    public static List<StructureElementCommand> excelToStructureElementCommands(InputStream is) {
+        // rules for conversion
+        //     Excel as StructureElementCommand accepted
+        //     Excel as StructureElement not accepted
+        //     see validateHeaderStructureElementCommand
+
+        int rowIndex = 0;
+        int columnIndex = 0;
+
+        try {
+              Workbook workbook = new XSSFWorkbook(is);
+              validateSheet(workbook);
+
+              Sheet sheet = workbook.getSheet(SHEET);
+              Iterator<Row> rows = sheet.iterator();
+              List<StructureElementCommand> list = Lists.newArrayList();
+
+              // iterate over rows and columns (cells)
+              while (rows.hasNext()) {
+                  Row row = rows.next();
+                  Iterator<Cell> cells = row.iterator();
+                  StructureElementCommand structureElementCommand = new StructureElementCommand();
+
+                  while (cells.hasNext()) {
+                      Cell cell = cells.next();
+                      rowIndex = cell.getRowIndex();
+                      columnIndex = cell.getColumnIndex();
+
+                      // ensure header row with syntax
+                      if (rowIndex == 0) {
+                          validateHeaderStructureElementCommand(cell);
+                          continue;
+                      }
+
+                      String value = cell.getStringCellValue();
+                      switch (columnIndex) {
+                      case 0:
+                          structureElementCommand.setUuid(!StringUtils.isEmpty(value) ? UUID.fromString(value) : null);
+                          break;
+                      case 1:
+                          structureElementCommand.setType(Type.valueOf(value));
+                          break;
+                      case 2:
+                          structureElementCommand.setParent(!StringUtils.isEmpty(value) ? UUID.fromString(value) : null);
+                          break;
+                      case 3:
+                          structureElementCommand.setName(value);
+                          break;
+                      case 4:
+                          structureElementCommand.setMnemonic(value);
+                          break;
+                      case 5:
+                          structureElementCommand.setDescription(value);
+                          break;
+                      case 6:
+                          structureElementCommand.setComment(value);
+                          break;
+                      default:
+                          throw new IllegalArgumentException(
+                                  MessageFormat.format(INVALID_VALUE_UNEXPECTED_VALUE, value));
+                      }
+
+                  }
+                  // not add header row
+                  if (rowIndex > 0) {
+                      list.add(structureElementCommand);
+                  }
+              }
+
+              workbook.close();
+              LOGGER.log(Level.INFO, ENTRIES_EXCEL_TO_STRUCTURE_ELEMENT_COMMANDS, list.size());
+              return list;
+        } catch (IllegalArgumentException | IOException e) {
+            throw new ServiceException(
+                    MessageFormat.format(FILE_COULD_NOT_BE_PARSED_FOR_VALUE_AT_ROW_CELL, rowIndex, columnIndex),
+                    e.getMessage(), null, e);
+        }
+    }
+
+    /**
+     * Validate that workbook has sheet with expected name.
+     *
+     * @param workbook workbook
+     */
+    private static void validateSheet(Workbook workbook) {
+        if (workbook.getSheet(SHEET) == null) {
+            throw new IllegalArgumentException(MessageFormat.format(INVALID_SHEET_EXPECTED_SHEET, SHEET));
+        }
+    }
+
+    /**
+     * Validate that cell is a proper header cell for a name element.
+     *
+     * @param cell cell
+     */
+    private static void validateHeaderNameElementCommand(Cell cell) {
+        // validate that columns are NameElementCommand
+        //     nothing less or more
+        //     not have (cell.getColumnIndex() >= NAMEELEMENTCOMMAND_LENGTH) to allow NameElement
+
+        if (cell.getColumnIndex() < NAMEELEMENTCOMMAND_LENGTH
+                && !NAMEELEMENT_HEADER_COMMENT[cell.getColumnIndex()][0].equals(cell.getStringCellValue())) {
+            throw new IllegalArgumentException(
+                    MessageFormat.format(
+                            INVALID_VALUE_EXPECTED_VALUE,
+                            cell.getStringCellValue(),
+                            NAMEELEMENT_HEADER_COMMENT[cell.getColumnIndex()][0]));
+        } else if (cell.getColumnIndex() >= NAMEELEMENTCOMMAND_LENGTH) {
+            throw new IllegalArgumentException(
+                    MessageFormat.format(INVALID_VALUE_UNEXPECTED_VALUE, cell.getStringCellValue()));
+        }
+    }
+
+    /**
+     * Validate that cell is a proper header cell for a structure element.
+     *
+     * @param cell cell
+     */
+    private static void validateHeaderStructureElementCommand(Cell cell) {
+        // validate that columns are StructureElementCommand
+        //     nothing less or more
+        //     not have (cell.getColumnIndex() >= STRUCTUREELEMENTCOMMAND_LENGTH) to allow StructureElement
+
+        if (cell.getColumnIndex() < STRUCTUREELEMENTCOMMAND_LENGTH
+                && !STRUCTUREELEMENT_HEADER_COMMENT[cell.getColumnIndex()][0].equals(cell.getStringCellValue())) {
+            throw new IllegalArgumentException(
+                    MessageFormat.format(
+                            INVALID_VALUE_EXPECTED_VALUE,
+                            cell.getStringCellValue(),
+                            STRUCTUREELEMENT_HEADER_COMMENT[cell.getColumnIndex()][0]));
+        } else if (cell.getColumnIndex() >= STRUCTUREELEMENTCOMMAND_LENGTH) {
+            throw new IllegalArgumentException(
+                    MessageFormat.format(INVALID_VALUE_UNEXPECTED_VALUE, cell.getStringCellValue()));
+        }
+    }
+
+    /**
+     * Utility method to convert a list of name elements to an Excel file.
+     *
+     * @param nameElements name elements
+     * @return Excel file
+     */
+    public static ByteArrayInputStream nameElementsToExcel(ResponsePageNameElements nameElements) {
+        return nameElementsToExcel(nameElements.getList());
+    }
+
+    /**
+     * Utility method to convert a list of name elements to an Excel file.
+     *
+     * @param nameElements name elements
+     * @return Excel file
+     */
+    public static ByteArrayInputStream nameElementsToExcel(List<NameElement> nameElements) {
+        LOGGER.log(Level.INFO, ENTRIES_NAME_ELEMENTS_TO_EXCEL, nameElements.size());
+        try (Workbook workbook = new XSSFWorkbook(); ByteArrayOutputStream out = new ByteArrayOutputStream();) {
+            Sheet sheet = workbook.createSheet(SHEET);
+
+            // prepare header
+            Drawing<?> drawing = sheet.createDrawingPatriarch();
+            CreationHelper factory = workbook.getCreationHelper();
+            ClientAnchor anchor = factory.createClientAnchor();
+            DataFormat format = workbook.createDataFormat();
+            short textFormat = format.getFormat("text");
+            Font headerFont = workbook.createFont();
+            headerFont.setBold(true);
+
+            // header
+            Row headerRow = sheet.createRow(0);
+            for (int columnIndex = 0; columnIndex < NAMEELEMENT_HEADER_COMMENT.length; columnIndex++) {
+                Cell cell = headerRow.createCell(columnIndex);
+
+                // value
+                cell.setCellValue(NAMEELEMENT_HEADER_COMMENT[columnIndex][0]);
+
+                // width
+                sheet.setColumnWidth(columnIndex, SHEET_COLUMN_WIDTH);
+
+                // style
+                CellStyle cellStyle = cell.getCellStyle();
+                cellStyle.setDataFormat(textFormat);
+                cellStyle.setFont(headerFont);
+                cell.setCellStyle(cellStyle);
+
+                // comment
+                anchor.setRow1(headerRow.getRowNum());
+                anchor.setRow2(headerRow.getRowNum()+3);
+                anchor.setCol1(cell.getColumnIndex());
+                anchor.setCol2(cell.getColumnIndex()+1);
+                Comment cellComment = drawing.createCellComment(anchor);
+                RichTextString richTextString = factory.createRichTextString(NAMEELEMENT_HEADER_COMMENT[columnIndex][1]);
+                cellComment.setString(richTextString);
+                cellComment.setAuthor(TextUtil.NAMING);
+                cell.setCellComment(cellComment);
+            }
+
+            // data
+            int rowIndex = 1;
+            for (NameElement nameElement : nameElements) {
+              Row row = sheet.createRow(rowIndex++);
+              row.createCell(0).setCellValue(nameElement.getUuid() != null ? nameElement.getUuid().toString() : null);
+              row.createCell(1).setCellValue(nameElement.getParentsystemstructure() != null ? nameElement.getParentsystemstructure().toString() : null);
+              row.createCell(2).setCellValue(nameElement.getParentdevicestructure() != null ? nameElement.getParentdevicestructure().toString() : null);
+              row.createCell(3).setCellValue(nameElement.getIndex());
+              row.createCell(4).setCellValue(nameElement.getDescription());
+              row.createCell(5).setCellValue(nameElement.getComment());
+              row.createCell(6).setCellValue(nameElement.getSystemstructure());
+              row.createCell(7).setCellValue(nameElement.getDevicestructure());
+              row.createCell(8).setCellValue(nameElement.getName());
+              row.createCell(9).setCellValue(nameElement.getStatus() != null ? nameElement.getStatus().toString() : null);
+              row.createCell(10).setCellValue(nameElement.isLatest());
+              row.createCell(11).setCellValue(nameElement.isDeleted());
+              row.createCell(12).setCellValue(DateFormat.getDateTimeInstance().format(nameElement.getWhen()));
+              row.createCell(13).setCellValue(nameElement.getWho());
+            }
+            workbook.write(out);
+            return new ByteArrayInputStream(out.toByteArray());
+
+        } catch (IOException e) {
+            throw new ServiceException(FAILED_TO_EXPORT_VALUES_TO_FILE, e.getMessage(), null, e);
+        }
+    }
+
+    /**
+     * Utility method to convert a list of structure elements to an Excel file.
+     *
+     * @param structureElements structure elements
+     * @return Excel file
+     */
+    public static ByteArrayInputStream structureElementsToExcel(ResponsePageStructureElements structureElements) {
+        return structureElementsToExcel(structureElements.getList());
+    }
+
+    /**
+     * Utility method to convert a list of structure elements to an Excel file.
+     *
+     * @param structureElements structure elements
+     * @return Excel file
+     */
+    public static ByteArrayInputStream structureElementsToExcel(List<StructureElement> structureElements) {
+        LOGGER.log(Level.INFO, ENTRIES_STRUCTURE_ELEMENTS_TO_EXCEL, structureElements.size());
+        try (Workbook workbook = new XSSFWorkbook(); ByteArrayOutputStream out = new ByteArrayOutputStream();) {
+            Sheet sheet = workbook.createSheet(SHEET);
+
+            // prepare header
+            Drawing<?> drawing = sheet.createDrawingPatriarch();
+            CreationHelper factory = workbook.getCreationHelper();
+            ClientAnchor anchor = factory.createClientAnchor();
+            DataFormat format = workbook.createDataFormat();
+            short textFormat = format.getFormat("text");
+            Font headerFont = workbook.createFont();
+            headerFont.setBold(true);
+
+            // header
+            Row headerRow = sheet.createRow(0);
+            for (int columnIndex = 0; columnIndex < STRUCTUREELEMENT_HEADER_COMMENT.length; columnIndex++) {
+              Cell cell = headerRow.createCell(columnIndex);
+
+              // value
+              cell.setCellValue(STRUCTUREELEMENT_HEADER_COMMENT[columnIndex][0]);
+
+              // width
+              sheet.setColumnWidth(columnIndex, SHEET_COLUMN_WIDTH);
+
+              // style
+              CellStyle cellStyle = cell.getCellStyle();
+              cellStyle.setDataFormat(textFormat);
+              cellStyle.setFont(headerFont);
+              cell.setCellStyle(cellStyle);
+
+              // comment
+              anchor.setRow1(headerRow.getRowNum());
+              anchor.setRow2(headerRow.getRowNum()+3);
+              anchor.setCol1(cell.getColumnIndex());
+              anchor.setCol2(cell.getColumnIndex()+1);
+              Comment cellComment = drawing.createCellComment(anchor);
+              RichTextString richTextString = factory.createRichTextString(STRUCTUREELEMENT_HEADER_COMMENT[columnIndex][1]);
+              cellComment.setString(richTextString);
+              cellComment.setAuthor(TextUtil.NAMING);
+              cell.setCellComment(cellComment);
+            }
+
+            // data
+            int rowIndex = 1;
+            for (StructureElement structureElement : structureElements) {
+              Row row = sheet.createRow(rowIndex++);
+              row.createCell(0).setCellValue(structureElement.getUuid() != null ? structureElement.getUuid().toString() : null);
+              row.createCell(1).setCellValue(structureElement.getType() != null ? structureElement.getType().toString() : null);
+              row.createCell(2).setCellValue(structureElement.getParent() != null ? structureElement.getParent().toString() : null);
+              row.createCell(3).setCellValue(structureElement.getName());
+              row.createCell(4).setCellValue(structureElement.getMnemonic());
+              row.createCell(5).setCellValue(structureElement.getDescription());
+              row.createCell(6).setCellValue(structureElement.getComment());
+              row.createCell(7).setCellValue(structureElement.getMnemonicpath());
+              row.createCell(8).setCellValue(structureElement.getLevel());
+              row.createCell(9).setCellValue(structureElement.getStatus() != null ? structureElement.getStatus().toString() : null);
+              row.createCell(10).setCellValue(structureElement.isLatest());
+              row.createCell(11).setCellValue(structureElement.isDeleted());
+              row.createCell(12).setCellValue(DateFormat.getDateTimeInstance().format(structureElement.getWhen()));
+              row.createCell(13).setCellValue(structureElement.getWho());
+            }
+            workbook.write(out);
+            return new ByteArrayInputStream(out.toByteArray());
+
+        } catch (IOException e) {
+            throw new ServiceException(FAILED_TO_EXPORT_VALUES_TO_FILE, e.getMessage(), null, e);
+        }
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/util/TextUtil.java b/src/main/java/org/openepics/names/util/TextUtil.java
index 3701117c2ab036beee3c153f9ef9b5db69e4f7b4..47fd1efc4cd4810bc47760210972e2ad34458219 100644
--- a/src/main/java/org/openepics/names/util/TextUtil.java
+++ b/src/main/java/org/openepics/names/util/TextUtil.java
@@ -120,6 +120,8 @@ public class TextUtil {
     public static final String INDEX_IS_NOT_VALID                      = INDEX            + SPACE + IS_NOT_VALID;
     public static final String MNEMONIC_IS_NOT_VALID                   = MNEMONIC         + SPACE + IS_NOT_VALID;
 
+    public static final String FILE_COULD_NOT_BE_PARSED                = "File could not be parsed";
+
     /**
      * This class is not to be instantiated.
      */
diff --git a/src/main/resources/application-docker.properties b/src/main/resources/application-docker.properties
index 102c01b5f1bfdb7c5be10bbc7475bf2f1f8161be..272502d963f6af947fed1338d8d53989becacaf3 100644
--- a/src/main/resources/application-docker.properties
+++ b/src/main/resources/application-docker.properties
@@ -22,8 +22,9 @@ openapi.info.contact.url=https://jira.esss.lu.se/projects/NT/issues
 openapi.info.description=\
   Perform Naming tasks Create Read Update Delete + Approve Cancel Reject \n\n \
   Here are some useful links \n \
-  - [CCDB ecosystem](https://confluence.esss.lu.se/display/SW/CCDB+ecosystem) \n \
-  - [Introduction to Naming REST API](/pdfs/naming_rest_api_brief_introduction.pdf) + [Cheat Sheet](/pdfs/naming_rest_api_cheat_sheet.pdf) \n\n \
+  - [Naming](https://confluence.esss.lu.se/display/SW/Naming+Tool%2C+Cable+DB%2C+CCDB%2C+IOC+Factory%2C+RBAC) in ICS Software toolchain \n \
+  - [Introduction to Naming REST API](/pdfs/naming_rest_api_brief_introduction.pdf) + [Cheat Sheet](/pdfs/naming_rest_api_cheat_sheet.pdf) \n \
+  - Excel templates for [names](/templates/NameElementCommand.xlsx) + [structures](/templates/StructureElementCommand.xlsx) \n\n \
   Note \n \
   - Observe which fields to use for operations client to server. \n \
   - Obsolete values are not shown unless history is requested. \n \
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 102c01b5f1bfdb7c5be10bbc7475bf2f1f8161be..272502d963f6af947fed1338d8d53989becacaf3 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -22,8 +22,9 @@ openapi.info.contact.url=https://jira.esss.lu.se/projects/NT/issues
 openapi.info.description=\
   Perform Naming tasks Create Read Update Delete + Approve Cancel Reject \n\n \
   Here are some useful links \n \
-  - [CCDB ecosystem](https://confluence.esss.lu.se/display/SW/CCDB+ecosystem) \n \
-  - [Introduction to Naming REST API](/pdfs/naming_rest_api_brief_introduction.pdf) + [Cheat Sheet](/pdfs/naming_rest_api_cheat_sheet.pdf) \n\n \
+  - [Naming](https://confluence.esss.lu.se/display/SW/Naming+Tool%2C+Cable+DB%2C+CCDB%2C+IOC+Factory%2C+RBAC) in ICS Software toolchain \n \
+  - [Introduction to Naming REST API](/pdfs/naming_rest_api_brief_introduction.pdf) + [Cheat Sheet](/pdfs/naming_rest_api_cheat_sheet.pdf) \n \
+  - Excel templates for [names](/templates/NameElementCommand.xlsx) + [structures](/templates/StructureElementCommand.xlsx) \n\n \
   Note \n \
   - Observe which fields to use for operations client to server. \n \
   - Obsolete values are not shown unless history is requested. \n \
diff --git a/src/main/resources/static/templates/NameElementCommand.xlsx b/src/main/resources/static/templates/NameElementCommand.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..04db6c54a4d35f2b81fd79e2827ba481bb54b4d5
Binary files /dev/null and b/src/main/resources/static/templates/NameElementCommand.xlsx differ
diff --git a/src/main/resources/static/templates/StructureElementCommand.xlsx b/src/main/resources/static/templates/StructureElementCommand.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..95ac1775957aced5957b45ddbb8e1191b4687112
Binary files /dev/null and b/src/main/resources/static/templates/StructureElementCommand.xlsx differ