diff --git a/src/frontend/app/administration/administration.module.ts b/src/frontend/app/administration/administration.module.ts
index aeacf866e6f77235fba83fa75ad6ae437a1fde63..4a76714578f744f47acda5f5b386110662507d59 100755
--- a/src/frontend/app/administration/administration.module.ts
+++ b/src/frontend/app/administration/administration.module.ts
@@ -21,6 +21,7 @@ import { BasketAdministrationComponent, BasketAdministrationSettingsModalCompone
 import { BasketsAdministrationComponent } from './basket/baskets-administration.component';
 import { ContactDuplicateComponent } from './contact/contact-duplicate/contact-duplicate.component';
 import { ContactExportComponent } from './contact/list/export/contact-export.component';
+import { ContactImportComponent } from './contact/list/import/contact-import.component';
 import { ContactsCustomFieldsAdministrationComponent } from './contact/customField/contacts-custom-fields-administration.component';
 import { ContactsGroupAdministrationComponent } from './contact/group/contacts-group-administration.component';
 import { ContactsGroupsAdministrationComponent } from './contact/group/contacts-groups-administration.component';
@@ -99,6 +100,7 @@ import { RegisteredMailListComponent } from './registered-mail/registered-mail-l
         BasketsAdministrationComponent,
         ContactDuplicateComponent,
         ContactExportComponent,
+        ContactImportComponent,
         ContactsCustomFieldsAdministrationComponent,
         ContactsGroupAdministrationComponent,
         ContactsGroupsAdministrationComponent,
@@ -164,6 +166,7 @@ import { RegisteredMailListComponent } from './registered-mail/registered-mail-l
         BasketAdministrationGroupListModalComponent,
         BasketAdministrationSettingsModalComponent,
         ContactExportComponent,
+        ContactImportComponent,
         ContactsListAdministrationRedirectModalComponent,
         DoctypesAdministrationRedirectModalComponent,
         EntitiesAdministrationRedirectModalComponent,
diff --git a/src/frontend/app/administration/contact/list/contacts-list-administration.component.html b/src/frontend/app/administration/contact/list/contacts-list-administration.component.html
index 3eab432026791e590e90bae0e629a2237735c8aa..3be7f487efb5d14d948fd2ea4285aba9aeb36a14 100755
--- a/src/frontend/app/administration/contact/list/contacts-list-administration.component.html
+++ b/src/frontend/app/administration/contact/list/contacts-list-administration.component.html
@@ -14,6 +14,12 @@
                     {{'lang.exportContacts' | translate}}
                 </p>
             </a>
+            <a mat-list-item (click)="openContactImportModal()">
+                <mat-icon color="primary" mat-list-icon class="fas fa-file-import"></mat-icon>
+                <p mat-line>
+                    {{'lang.importContacts' | translate}}
+                </p>
+            </a>
         </mat-nav-list>
         <mat-divider></mat-divider>
         <mat-nav-list>
diff --git a/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts b/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts
index b19e7de83e956f6f0ac19131a23f61b78b88e585..e75a60957ec5fdd2ca7371f0302f0e43418180cd 100644
--- a/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts
+++ b/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts
@@ -15,6 +15,7 @@ import { FormControl } from '@angular/forms';
 import { FunctionsService } from '../../../../service/functions.service';
 import { ContactExportComponent } from './export/contact-export.component';
 import { AdministrationService } from '../../../../app/administration/administration.service';
+import { ContactImportComponent } from './import/contact-import.component';
 
 @Component({
     selector: 'contact-list',
@@ -229,6 +230,26 @@ export class ContactsListAdministrationComponent implements OnInit {
         this.dialog.open(ContactExportComponent, { panelClass: 'maarch-modal', width: '800px', autoFocus: false });
     }
 
+    openContactImportModal() {
+        const dialogRef = this.dialog.open(ContactImportComponent, {
+            disableClose: true,
+            width: '99vw',
+            maxWidth: '99vw',
+            panelClass: 'maarch-full-height-modal'
+        });
+
+        dialogRef.afterClosed().pipe(
+            filter((data: any) => data === 'success'),
+            tap(() => {
+                this.refreshDao();
+            }),
+            catchError((err: any) => {
+                this.notify.handleSoftErrors(err);
+                return of(false);
+            })
+        ).subscribe();
+    }
+
     refreshDao() {
         this.filtersChange.emit();
     }
diff --git a/src/frontend/app/administration/contact/list/import/contact-import.component.html b/src/frontend/app/administration/contact/list/import/contact-import.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..e225e162354a03012fe27ea6ed785ddc88574235
--- /dev/null
+++ b/src/frontend/app/administration/contact/list/import/contact-import.component.html
@@ -0,0 +1,91 @@
+<div class="mat-dialog-content-container">
+    <h1 mat-dialog-title>{{'lang.contactsImport' | translate}}</h1>
+    <div mat-dialog-content>
+        <mat-toolbar class="import-tool" [class.hide]="csvData.length === 0 || loading">
+            <span style="flex:1;">
+                <mat-slide-toggle color="primary" [checked]="hasHeader" (change)="toggleHeader()">En-tête csv
+                </mat-slide-toggle>
+            </span>
+            <span style="flex:1;text-align: center;"><i class="fa fa-users"
+                    color="primary"></i>&nbsp;{{'lang.contactsOfFile' | translate}} : <b color="primary">{{countAll}}</b>
+            </span>
+            <span style="flex:1;text-align: center;"><i class="fa fa-user-plus"
+                    color="primary"></i>&nbsp;{{'lang.additions' | translate}} : <b
+                    color="primary">{{countAdd}}</b></span>
+            <span style="flex:1;text-align: right;"><i class="fa fa-user-edit"
+                    color="primary"></i>&nbsp;{{'lang.modifications' | translate}} : <b
+                    color="primary">{{countUp}}</b></span>
+        </mat-toolbar>
+        <ng-container *ngIf="loading; else elseTemplate">
+            <div class="loader">
+                <mat-spinner></mat-spinner>
+            </div>
+        </ng-container>
+        <ng-template #elseTemplate>
+            <input type="file" name="files[]" #uploadFile id="uploadFile" (change)="uploadCsv($event)" accept=".csv"
+                style="display: none;">
+            <div *ngIf="csvData.length === 0" appUploadFileDragDrop (click)="uploadFile.click()"
+                (onFileDropped)="dndUploadFile($event)" class="dndFile">
+                <div>
+                    {{'lang.dndFileCsvDesc' | translate}}
+                    <mat-form-field appearance="outline" style="font-size:14px;" (click)="$event.stopPropagation()">
+                        <mat-label>{{'lang.delimiter' | translate}}</mat-label>
+                        <mat-select [(ngModel)]="currentDelimiter" (click)="$event.stopPropagation()">
+                            <mat-option *ngFor="let delimiter of delimiters" [value]="delimiter">
+                                {{delimiter === '\t' ? 'TAB' : delimiter}}
+                            </mat-option>
+                        </mat-select>
+                    </mat-form-field>
+                </div>
+            </div>
+            <div class="row" style="margin: 0px;">
+                <div class="col-md-12">
+                    <mat-paginator #paginator [length]="100" [hidePageSize]="true" [pageSize]="10">
+                    </mat-paginator>
+                </div>
+            </div>
+            <div style="width:100%;box-shadow: inset 0px 0px 5px 0px rgba(0,0,0,0.75);padding:10px;">
+                <div style="overflow: auto;">
+                    <mat-table *ngIf="csvData.length > 0" #table [dataSource]="dataSource" style="width:5000px;">
+                        <ng-container *ngFor="let column of contactColumns;let i=index;">
+                            <ng-container [matColumnDef]="column">
+                                <mat-header-cell *matHeaderCellDef>
+                                    <i class="fas fa-database" color="primary"
+                                        [title]="'lang.dbColumn' | translate"></i>&nbsp;<b color="primary"
+                                        [title]="'lang.dbColumn' | translate">{{column}}</b>
+                                    &nbsp;<i class="fas fa-arrows-alt-h"></i>&nbsp;
+                                    <i class="fas fa-file-csv" [title]="'lang.csvColumn' | translate"></i>&nbsp;
+                                    <mat-form-field [title]="'lang.csvColumn' | translate"
+                                        (click)="$event.stopPropagation()" style="width: 80px !important;">
+                                        <mat-select [(ngModel)]="associatedColmuns[column]"
+                                            (selectionChange)="changeColumn(column, $event.value)">
+                                            <mat-option value=""></mat-option>
+                                            <mat-option *ngFor="let col of csvColumns" [value]="col">
+                                                {{col}}
+                                            </mat-option>
+                                        </mat-select>
+                                    </mat-form-field>
+                                </mat-header-cell>
+                                <mat-cell *matCellDef="let element">
+                                    {{element[column]}}
+                                </mat-cell>
+                            </ng-container>
+                        </ng-container>
+                        <mat-header-row *matHeaderRowDef="contactColumns"></mat-header-row>
+                        <mat-row *matRowDef="let row; columns: contactColumns;"></mat-row>
+                    </mat-table>
+                </div>
+            </div>
+            <div class="alert-message alert-message-info" [innerHTML]="'lang.infoImportcontacts' | translate"
+                style="min-width: 100%">
+            </div>
+        </ng-template>
+    </div>
+    <span class="divider-modal"></span>
+    <div mat-dialog-actions class="actions">
+        <button mat-raised-button mat-button *ngIf="csvData.length > 0" color="primary" [disabled]="loading"
+            (click)="onSubmit()">{{'lang.validate' | translate}}</button>
+        <button mat-raised-button mat-button [disabled]="loading"
+            [mat-dialog-close]="">{{'lang.cancel' | translate }}</button>
+    </div>
+</div>
\ No newline at end of file
diff --git a/src/frontend/app/administration/contact/list/import/contact-import.component.scss b/src/frontend/app/administration/contact/list/import/contact-import.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a5f90325d237737ed4446eb7f3c98013bc28d3b3
--- /dev/null
+++ b/src/frontend/app/administration/contact/list/import/contact-import.component.scss
@@ -0,0 +1,27 @@
+@import '../../../../../css/vars.scss';
+
+.loader {
+    display: flex;
+    height: 100%;
+    align-items: center;
+    justify-content: center;
+}
+
+.hide {
+    display: none;
+}
+
+.import-tool {
+    font-size: 14px;
+}
+
+.dndFile {
+    height: 100%;
+    display: flex;
+    align-items: center;
+    margin: 0px;
+    justify-content: center;
+    font-size: 30px;
+    opacity: 0.5 !important;
+    cursor: pointer;
+}
\ No newline at end of file
diff --git a/src/frontend/app/administration/contact/list/import/contact-import.component.ts b/src/frontend/app/administration/contact/list/import/contact-import.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6d0f243d463239dddf0c3c2092d2cf8c6f21fdf3
--- /dev/null
+++ b/src/frontend/app/administration/contact/list/import/contact-import.component.ts
@@ -0,0 +1,254 @@
+import { Component, OnInit, Inject, ViewChild } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { NotificationService } from '../../../../../service/notification/notification.service';
+import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material/dialog';
+import { TranslateService } from '@ngx-translate/core';
+import { MatTableDataSource } from '@angular/material/table';
+import { FunctionsService } from '../../../../../service/functions.service';
+import { ConfirmComponent } from '../../../../../plugins/modal/confirm.component';
+import { filter, exhaustMap, tap, catchError } from 'rxjs/operators';
+import { of } from 'rxjs/internal/observable/of';
+import { AlertComponent } from '../../../../../plugins/modal/alert.component';
+import { LocalStorageService } from '../../../../../service/local-storage.service';
+import { HeaderService } from '../../../../../service/header.service';
+import { MatPaginator } from '@angular/material/paginator';
+
+@Component({
+    templateUrl: 'contact-import.component.html',
+    styleUrls: ['contact-import.component.scss']
+})
+export class ContactImportComponent implements OnInit {
+
+    loading: boolean = false;
+    contactColumns: string[] = [
+        'id',
+        'company',
+        'civility',
+        'firstname',
+        'lastname',
+        'function',
+        'department',
+        'email',
+        'addressAdditional1',
+        'addressNumber',
+        'addressStreet',
+        'addressAdditional2',
+        'addressPostcode',
+        'addressTown',
+        'addressCountry',
+        'communicationMeans',
+        'externalId_m2m',
+    ];
+
+    csvColumns: string[] = [
+
+    ];
+
+    delimiters = [';', ',', '\t'];
+    currentDelimiter = ';';
+
+    associatedColmuns: any = {};
+    dataSource = new MatTableDataSource(null);
+    hasHeader: boolean = true;
+    csvData: any[] = [];
+    contactData: any[] = [];
+    countAll: number = 0;
+    countAdd: number = 0;
+    countUp: number = 0;
+
+    @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
+
+    constructor(
+        public translate: TranslateService,
+        public http: HttpClient,
+        private notify: NotificationService,
+        private functionsService: FunctionsService,
+        private localStorage: LocalStorageService,
+        private headerService: HeaderService,
+        public dialog: MatDialog,
+        public dialogRef: MatDialogRef<ContactImportComponent>,
+        @Inject(MAT_DIALOG_DATA) public data: any,
+    ) {
+    }
+
+    ngOnInit(): void {
+        this.setConfiguration();
+    }
+
+    changeColumn(coldb: string, colCsv: string) {
+        this.contactData = [];
+        for (let index = this.hasHeader ? 1 : 0; index < this.csvData.length; index++) {
+            const data = this.csvData[index];
+
+            const objContact = {};
+
+            this.contactColumns.forEach(key => {
+                objContact[key] = coldb === key ? data[this.csvColumns.filter(col => col === colCsv)[0]] : data[this.associatedColmuns[key]];
+            });
+
+            this.contactData.push(objContact);
+        }
+
+        this.countAdd = this.csvData.filter((data: any, index: number) => index > 0 && this.functionsService.empty(data[this.associatedColmuns['id']])).length;
+        this.countUp = this.csvData.filter((data: any, index: number) => index > 0 && !this.functionsService.empty(data[this.associatedColmuns['id']])).length;
+
+        setTimeout(() => {
+            this.dataSource = new MatTableDataSource(this.contactData);
+            this.dataSource.paginator = this.paginator;
+        }, 0);
+    }
+
+    uploadCsv(fileInput: any) {
+        if (fileInput.target.files && fileInput.target.files[0] && fileInput.target.files[0].type === 'text/csv') {
+            this.loading = true;
+
+            let rawCsv = [];
+            const reader = new FileReader();
+
+            reader.readAsText(fileInput.target.files[0]);
+
+            reader.onload = (value: any) => {
+                rawCsv = value.target.result.split('\n');
+                rawCsv = rawCsv.filter(data => data !== '');
+
+                if (rawCsv[0].split(this.currentDelimiter).map(s => s.replace(/"/gi, '').trim()).length >= this.contactColumns.length - 1) {
+                    let dataCol = [];
+                    let objData = {};
+                    this.setCsvColumns(rawCsv[0].split(this.currentDelimiter).map(s => s.replace(/"/gi, '').trim()));
+
+                    this.countAll = this.hasHeader ? rawCsv.length - 1 : rawCsv.length;
+
+                    for (let index = 0; index < rawCsv.length; index++) {
+                        objData = {};
+                        dataCol = rawCsv[index].split(this.currentDelimiter).map(s => s.replace(/"/gi, '').trim());
+
+                        dataCol.forEach((element: any, index2: number) => {
+                            objData[this.csvColumns[index2]] = element;
+                        });
+                        this.csvData.push(objData);
+                    }
+                    this.initData();
+                    this.countAdd = this.csvData.filter((data: any, index: number) => index > 0 && this.functionsService.empty(data[this.associatedColmuns['id']])).length;
+                    this.countUp = this.csvData.filter((data: any, index: number) => index > 0 && !this.functionsService.empty(data[this.associatedColmuns['id']])).length;
+                    this.localStorage.save(`importContactFields_${this.headerService.user.id}`, this.currentDelimiter);
+                } else {
+                    this.notify.error(this.translate.instant('lang.mustAtLeastMinValues'));
+                }
+                this.loading = false;
+            };
+        } else {
+            this.dialog.open(AlertComponent, { panelClass: 'maarch-modal', autoFocus: false, disableClose: true, data: { title: this.translate.instant('lang.notAllowedExtension') + ' !', msg: this.translate.instant('lang.file') + ' : <b>' + fileInput.target.files[0].name + '</b>, ' + this.translate.instant('lang.type') + ' : <b>' + fileInput.target.files[0].type + '</b><br/><br/><u>' + this.translate.instant('lang.allowedExtensions') + '</u> : <br/>' + 'text/csv' } });
+        }
+    }
+
+    setCsvColumns(headerData: string[] = null) {
+        if (headerData.filter(col => this.functionsService.empty(col)).length > 0) {
+            this.csvColumns = Object.keys(headerData).map((val, index) => `${index}`);
+        } else {
+            this.csvColumns = headerData;
+        }
+    }
+
+    toggleHeader() {
+        this.hasHeader = !this.hasHeader;
+        this.countAll = this.hasHeader ? this.csvData.length - 1 : this.csvData.length;
+        if (this.hasHeader) {
+            this.countAdd = this.csvData.filter((data: any, index: number) => index > 0 && this.functionsService.empty(data[this.associatedColmuns['id']])).length;
+            this.countUp = this.csvData.filter((data: any, index: number) => index > 0 && !this.functionsService.empty(data[this.associatedColmuns['id']])).length;
+        } else {
+            this.countAdd = this.csvData.filter((data: any, index: number) => this.functionsService.empty(data[this.associatedColmuns['id']])).length;
+            this.countUp = this.csvData.filter((data: any, index: number) => !this.functionsService.empty(data[this.associatedColmuns['id']])).length;
+        }
+        this.initData();
+    }
+
+    initData() {
+        this.contactData = [];
+        for (let index = this.hasHeader ? 1 : 0; index < this.csvData.length; index++) {
+            const data = this.csvData[index];
+            const objContact = {};
+
+            this.contactColumns.forEach((key, indexCol) => {
+                this.associatedColmuns[key] = this.csvColumns[indexCol];
+                objContact[key] = data[this.csvColumns[indexCol]];
+            });
+            this.contactData.push(objContact);
+
+        }
+        setTimeout(() => {
+            this.dataSource = new MatTableDataSource(this.contactData);
+            this.dataSource.paginator = this.paginator;
+        }, 0);
+    }
+
+    dndUploadFile(event: any) {
+        const fileInput = {
+            target: {
+                files: [
+                    event[0]
+                ]
+            }
+        };
+        this.uploadCsv(fileInput);
+    }
+
+    onSubmit() {
+        const dataToSend: any[] = [];
+        let confirmText = '';
+        this.translate.get('lang.confirmImportUsers', { 0: this.countAll }).subscribe((res: string) => {
+            confirmText = `${res} ?<br/><br/>`;
+            confirmText += `<ul><li><b>${this.countAdd}</b> ${this.translate.instant('lang.additions')}</li><li><b>${this.countUp}</b> ${this.translate.instant('lang.modifications')}</li></ul>`;
+        });
+        let dialogRef = this.dialog.open(ConfirmComponent, { panelClass: 'maarch-modal', autoFocus: false, disableClose: true, data: { title: this.translate.instant('lang.import'), msg: confirmText } });
+        dialogRef.afterClosed().pipe(
+            filter((data: string) => data === 'ok'),
+            tap(() => {
+                this.loading = true;
+                this.csvData.forEach((element: any, index: number) => {
+                    if ((this.hasHeader && index > 0) || !this.hasHeader) {
+                        const objContact = {};
+                        this.contactColumns.forEach((key) => {
+                            objContact[key] = element[this.associatedColmuns[key]];
+                        });
+                        dataToSend.push(objContact);
+                    }
+                });
+            }),
+            exhaustMap(() => this.http.put(`../rest/users/import`, { users: dataToSend })),
+            tap((data: any) => {
+                let textModal = '';
+                if (data.warnings.count > 0) {
+                    textModal = `<br/>${data.warnings.count} ${this.translate.instant('lang.withWarnings')}  : <ul>`;
+                    data.errors.details.forEach(element => {
+                        textModal += `<li> ${this.translate.instant('element.lang')} (${this.translate.instant('lang.line')} : ${this.hasHeader ? element.index + 2 : element.index + 1})</li>`;
+                    });
+                    textModal += '</ul>';
+                }
+
+                if (data.errors.count > 0) {
+                    textModal += `<br/>${data.errors.count} ${this.translate.instant('lang.withErrors')}  : <ul>`;
+                    data.errors.details.forEach(element => {
+                        textModal += `<li> ${this.translate.instant('element.lang')} (${this.translate.instant('lang.line')} : ${this.hasHeader ? element.index + 2 : element.index + 1})</li>`;
+                    });
+                    textModal += '</ul>';
+                }
+                dialogRef = this.dialog.open(AlertComponent, { panelClass: 'maarch-modal', autoFocus: false, disableClose: true, data: { title: this.translate.instant('lang.import'), msg: '<b>' + data.success + '</b> / <b>' + this.countAll + '</b> ' + this.translate.instant('lang.importedUsers') + '.' + textModal } });
+            }),
+            exhaustMap(() => dialogRef.afterClosed()),
+            tap(() => {
+                this.dialogRef.close('success');
+            }),
+            catchError((err: any) => {
+                this.loading = false;
+                this.notify.handleSoftErrors(err);
+                return of(false);
+            })
+        ).subscribe();
+    }
+
+    setConfiguration() {
+        if (this.localStorage.get(`importContactFields_${this.headerService.user.id}`) !== null) {
+            this.currentDelimiter = this.localStorage.get(`importContactFields_${this.headerService.user.id}`);
+        }
+    }
+}