diff --git a/fid/config/vufind/fid.ini b/fid/config/vufind/fid.ini
index 1739235747aa01027b1faf8e1a942c3f072b1a4a..2ebd332e98b8e8539ede0475ccf94ce773e5650f 100644
--- a/fid/config/vufind/fid.ini
+++ b/fid/config/vufind/fid.ini
@@ -23,4 +23,7 @@ overview_fields[] = 'Permissions'
 ; List of all available user permissions
 permission_options[] = 'basic_access'
 permission_options[] = 'limited_access'
-permission_options[] = 'full_access'
\ No newline at end of file
+permission_options[] = 'full_access'
+
+; file prefix for CSV export
+user_list_export_file_prefix = 'export'
\ No newline at end of file
diff --git a/module/fid/config/module.config.php b/module/fid/config/module.config.php
index c4464b068d70101ada8913673d170824d57c1bed..77f8d58bbe0bafcd1fdc34d859b33df8e1d6b47a 100644
--- a/module/fid/config/module.config.php
+++ b/module/fid/config/module.config.php
@@ -349,7 +349,17 @@ $config = [
                                     ],
                                 ],
                             ],
-                            'edit' => [
+                            'exportList'          => [
+                                'type'    => 'literal',
+                                'options' => [
+                                    'route'    => '/exportList',
+                                    'defaults' => [
+                                        'controller' => UserController::class,
+                                        'action'     => 'exportList',
+                                    ],
+                                ],
+                            ],
+                            'edit'          => [
                                 'type'    => 'Zend\Router\Http\Segment',
                                 'options' => [
                                     'route'    => '/edit/[:userid]',
diff --git a/module/fid/config/user-init-form.php b/module/fid/config/user-init-form.php
index 0718f0fa86d70aa22a2a36ef93f88a05be361d7c..5ab7b2f2bb041100a9a2a0fb2c4478f205d769a8 100644
--- a/module/fid/config/user-init-form.php
+++ b/module/fid/config/user-init-form.php
@@ -51,7 +51,7 @@ return [
         'username_confirmation' => [
             'spec' => [
                 'name'       => 'username_confirmation',
-                'type'       => Text::class,
+                'type'       => Email::class,
                 'options'    => [
                     'label' => 'label_username_confirmation',
                 ],
diff --git a/module/fid/src/Controller/UserController.php b/module/fid/src/Controller/UserController.php
index 7eb04a7da71cacdf802bfdbbe83e0ee5798ecb07..568baa6ab2bd892009f7422883c9d0d541e91a56 100644
--- a/module/fid/src/Controller/UserController.php
+++ b/module/fid/src/Controller/UserController.php
@@ -42,6 +42,7 @@ use Zend\Http\Response;
 use Zend\Mvc\Plugin\FlashMessenger\FlashMessenger;
 use Zend\ServiceManager\ServiceLocatorInterface;
 use Zend\View\Model\ViewModel;
+use Zend\Http\PhpEnvironment\Response as HttpResponse;
 
 class UserController extends AbstractBase
 {
@@ -744,4 +745,44 @@ class UserController extends AbstractBase
         return false;
     }
 
+    /**
+     * @return HttpResponse
+     * @throws ClientException
+     * @throws UserNotAuthorizedException
+     */
+    public function exportListAction()
+    {
+        $userList = $this->client->requestUserList();
+        $fields = $this->config['Admin']['export_fields'] ?? null;
+        if (empty($fields)) {
+            $fields = current($userList)->getFieldList();
+        }
+        return $this->createExportFile(
+            $userList,
+            $fields
+        );
+    }
+
+    protected function createExportFile($userList, $fields=null)
+    {
+
+        $response = new HttpResponse();
+        $prefix = $this->config['Admin']['user_list_export_file_prefix'] ?? 'export';
+        $response->getHeaders()->addHeaders(
+            [
+                'Content-type' => 'text/plain',
+                'Content-Disposition' => 'attachment; filename="'.$prefix.'_'.date('Ymd_His').'.csv"'
+            ]
+        );
+        $output = implode("\t",$fields)."\n";
+        foreach ($userList as $user) {
+            // we need to load the actual user object since some
+            // properties are missing from the overview list
+            $user = $this->client->requestUserDetails($user->id);
+            $output .= $user->export($fields)."\n";
+        }
+        $response->setContent($output);
+        return $response;
+    }
+
 }
diff --git a/module/fid/src/Service/DataTransferObject/Address.php b/module/fid/src/Service/DataTransferObject/Address.php
index 40cdf437042efd0f3a1c8c55ad91157ad9776259..7ea09cd11bfb1493a6368b2c80d2c7bcb21097c7 100644
--- a/module/fid/src/Service/DataTransferObject/Address.php
+++ b/module/fid/src/Service/DataTransferObject/Address.php
@@ -212,4 +212,9 @@ class Address
     {
         $this->country = $country;
     }
+
+    public function __toString()
+    {
+        return $this->id.': '. $this->line1.' '.$this->line2.'; '.$this->zip.' '.$this->city.'; '.$this->country;
+    }
 }
diff --git a/module/fid/src/Service/DataTransferObject/Order.php b/module/fid/src/Service/DataTransferObject/Order.php
index d2475b59f4cfdd2eddd3fda17facb2ac2149afc8..51863f887a8ea3918357a8662023cfbd21177222 100644
--- a/module/fid/src/Service/DataTransferObject/Order.php
+++ b/module/fid/src/Service/DataTransferObject/Order.php
@@ -198,4 +198,9 @@ class Order
     {
         $this->createdAt = $createdAt;
     }
+
+    public function __toString()
+    {
+        return $this->getLabel();
+    }
 }
\ No newline at end of file
diff --git a/module/fid/src/Service/DataTransferObject/User.php b/module/fid/src/Service/DataTransferObject/User.php
index af8eb64aa06da3038fc3500c3f079b373b5b4545..a54f4d66d7e185f5f1ca6435e4b326d16f960cbc 100644
--- a/module/fid/src/Service/DataTransferObject/User.php
+++ b/module/fid/src/Service/DataTransferObject/User.php
@@ -494,4 +494,45 @@ class User
     public function getLiberoId () : string {
         return 'FID'.str_pad($this->getId(),10,"0",STR_PAD_LEFT);
     }
+
+    public function getFieldList()
+    {
+        $fields = [];
+        foreach ($this as $property => $value) {
+            if ($property === 'password') continue;
+            $fields[] = $property;
+        }
+        return $fields;
+    }
+
+    public function export($fields,$delimiter="\t") {
+
+        $output = '';
+        foreach ($fields as $property) {
+            if ($property === 'password') continue;
+            if ($property === 'permissions') {
+                $value = [];
+                $permissions = $this->getPermissions();
+                foreach ($permissions as $key => $perm) {
+                    $value[] = $key.' ('.$perm.')';
+                }
+            } else {
+                $value = $this->{$property} ?? '';
+                if ($property === 'data' && is_array($value))
+                {
+                    array_walk(
+                        $value,
+                        function(&$data,$key) {
+                            $data = $key.': '.($data ? 'yes': 'no');
+                        }
+                    );
+                }
+            }
+            if (is_array($value)) {
+                $value = implode(', ', $value);
+            }
+            $output .= $value . $delimiter;
+        }
+        return rtrim($output,$delimiter);
+    }
 }
diff --git a/themes/fid/languages/fid/de.ini b/themes/fid/languages/fid/de.ini
index 9e3e16e570023de702f87ef9f4375039a72b6988..64f3766f63e11efc3cef5cf7746f2374e25ce9a4 100644
--- a/themes/fid/languages/fid/de.ini
+++ b/themes/fid/languages/fid/de.ini
@@ -115,6 +115,7 @@ user_edit_not_allowed = "Sie haben keine Berechtigung Nutzer %%userid%% zu editi
 user_read_error = "Fehler beim Lesen der Daten von Nutzer %%userid%%"
 read_user_list_not_allowed = "Sie haben keine Berechtigung die Nutzerliste einzusehen"
 read_user_list_error = "Fehler beim Lesen der Nutzerliste"
+user_list_export = "CSV-Export"
 read_order_list_not_allowed = "Sie haben keine Berechtigung die Bestellliste einzusehen"
 
 user_edit_form_title = "Nutzerdaten ändern für <em>%%username%%</em> (ID %%userid%%)"
diff --git a/themes/fid/languages/fid/en.ini b/themes/fid/languages/fid/en.ini
index 45291196faabba6997c7f74c11b2270f9cfc5687..82ebbb769268e5140b08c0a2d3f730b78bad69a1 100644
--- a/themes/fid/languages/fid/en.ini
+++ b/themes/fid/languages/fid/en.ini
@@ -113,6 +113,7 @@ user_edit_not_allowed = "You are not entitled to edit user %%userid%%"
 user_read_error = "Error reading data of user %%userid%%"
 read_user_list_not_allowed = "You are not entitled to read the user list"
 read_user_list_error = "Error reading user list"
+user_list_export = "CSV-Export"
 read_order_list_not_allowed = "You are not entitled to read the order list"
 
 user_edit_form_title = "Edit user data of <em>%%username%%</em> (ID %%userid%%)"
diff --git a/themes/fid/templates/fid/admin/list.phtml b/themes/fid/templates/fid/admin/list.phtml
index 3d0c9fefd4a38cab6481f753689144e0074ce41b..ddf7bf9825e47d9c86bc936ba084633f542de1a7 100644
--- a/themes/fid/templates/fid/admin/list.phtml
+++ b/themes/fid/templates/fid/admin/list.phtml
@@ -15,6 +15,7 @@
         <tr><td><a href="<?=$this->url('fid/admin/edit',['userid' => $id])?>" title="<?=$tooltip?>"><i class="fa fa-pencil-square-o"></i><span class="sr-only"><?=$tooltip?></span></a></td><th><?=$id?></th><?= $this->render('fid/admin/list-entry',['user' => $user,'fields'=>$fields, 'config' => $config]) ?></tr>
     <?php endforeach; ?>
     </table>
+    <a href="<?=$this->url('fid/admin/exportList')?>" class="btn btn-primary" target="_blank"><i class="fa fa-download"></i> <?=$this->translate('fid::user_list_export')?></a>
 <?php else: ?>
     <?= $this->translate('fid::user_list_empty') ?>
 <?php endif; ?>