diff --git a/src/app/core/export/download-service/download.service.spec.ts b/src/app/core/export/download-service/download.service.spec.ts
index 9ae04ea0ce..c45574a155 100644
--- a/src/app/core/export/download-service/download.service.spec.ts
+++ b/src/app/core/export/download-service/download.service.spec.ts
@@ -49,6 +49,7 @@ describe("DownloadService", () => {
     // reset createElement otherwise results in: 'an Error was thrown after all'
     document.createElement = oldCreateElement;
   });
+
   it("should contain a column for every property", async () => {
     const docs = [
       { _id: "Test:1", test: 1 },
@@ -77,11 +78,12 @@ describe("DownloadService", () => {
       '"_id","_rev","propOne","propTwo"' +
       DownloadService.SEPARATOR_ROW +
       '"TestForCsvEntity:1","2","first","second"';
+    spyOn(service, "exportFile").and.returnValue(expected);
     const result = await service.createCsv([test]);
     expect(result).toEqual(expected);
   });
 
-  it("should transform object properties to their label for export", async () => {
+  it("should transform object values to their label for export when available (e.g. configurable-enum)", async () => {
     const testEnumValue: ConfigurableEnumValue = {
       id: "ID VALUE",
       label: "label value",
@@ -90,9 +92,10 @@ describe("DownloadService", () => {
 
     @DatabaseEntity("TestEntity")
     class TestEntity extends Entity {
-      @DatabaseField() enumProperty: ConfigurableEnumValue;
-      @DatabaseField() dateProperty: Date;
-      @DatabaseField() boolProperty: boolean;
+      @DatabaseField({ label: "test enum" })
+      enumProperty: ConfigurableEnumValue;
+      @DatabaseField({ label: "test date" }) dateProperty: Date;
+      @DatabaseField({ label: "test boolean" }) boolProperty: boolean;
     }
 
     const testEntity = new TestEntity();
@@ -105,12 +108,65 @@ describe("DownloadService", () => {
     const rows = csvExport.split(DownloadService.SEPARATOR_ROW);
     expect(rows).toHaveSize(1 + 1); // includes 1 header line
     const columnValues = rows[1].split(DownloadService.SEPARATOR_COL);
-    expect(columnValues).toHaveSize(3 + 1); // Properties + _id
+    expect(columnValues).toHaveSize(3); // Properties (_id is filter out by default)
     expect(columnValues).toContain('"' + testEnumValue.label + '"');
     expect(columnValues).toContain('"' + testDate + '"');
     expect(columnValues).toContain('"true"');
   });
 
+  it("should export all properties using object keys as headers, if no schema is available", async () => {
+    const docs = [
+      { _id: "Test:1", name: "Child 1" },
+      { _id: "Test:2", name: "Child 2" },
+    ];
+
+    const csvExport = await service.createCsv(docs);
+
+    const rows = csvExport.split(DownloadService.SEPARATOR_ROW);
+    expect(rows).toHaveSize(2 + 1); // includes 1 header line
+    const columnHeaders = rows[0].split(DownloadService.SEPARATOR_COL);
+    const columnValues = rows[1].split(DownloadService.SEPARATOR_COL);
+
+    expect(columnValues).toHaveSize(2);
+    expect(columnHeaders).toHaveSize(2);
+    expect(columnHeaders).toContain('"_id"');
+  });
+
+  it("should only export columns that have labels defined in entity schema and use the schema labels as export headers", async () => {
+    const testString: string = "Test 1";
+
+    @DatabaseEntity("LabelTestEntity")
+    class LabelTestEntity extends Entity {
+      @DatabaseField({ label: "test string" }) stringProperty: string;
+      @DatabaseField({ label: "test date" }) otherProperty: string;
+      @DatabaseField() boolProperty: boolean;
+    }
+
+    const labelTestEntity = new LabelTestEntity();
+    labelTestEntity.stringProperty = testString;
+    labelTestEntity.otherProperty = "x";
+    labelTestEntity.boolProperty = true;
+
+    const incompleteTestEntity = new LabelTestEntity();
+    incompleteTestEntity.otherProperty = "second row";
+
+    const csvExport = await service.createCsv([
+      labelTestEntity,
+      incompleteTestEntity,
+    ]);
+
+    const rows = csvExport.split(DownloadService.SEPARATOR_ROW);
+    expect(rows).toHaveSize(1 + 2); // includes 1 header line
+
+    const columnHeaders = rows[0].split(DownloadService.SEPARATOR_COL);
+    expect(columnHeaders).toHaveSize(2);
+    expect(columnHeaders).toContain('"test string"');
+    expect(columnHeaders).toContain('"test date"');
+
+    const entity2Values = rows.find((r) => r.includes("second row"));
+    expect(entity2Values).toEqual(',"second row"'); // first column empty!
+  });
+
   it("should export a date as YYYY-MM-dd only", async () => {
     const dateString = "2021-01-01";
     const dateObject = moment(dateString).toDate();
diff --git a/src/app/core/export/download-service/download.service.ts b/src/app/core/export/download-service/download.service.ts
index 147df776db..57fe6180fc 100644
--- a/src/app/core/export/download-service/download.service.ts
+++ b/src/app/core/export/download-service/download.service.ts
@@ -5,6 +5,7 @@ import { LoggingService } from "../../logging/logging.service";
 import { DataTransformationService } from "../data-transformation-service/data-transformation.service";
 import { transformToReadableFormat } from "../../common-components/entity-subrecord/entity-subrecord/value-accessor";
 import { Papa } from "ngx-papaparse";
+import { EntitySchemaField } from "app/core/entity/schema/entity-schema-field";
 
 /**
  * This service allows to start a download process from the browser.
@@ -90,17 +91,62 @@ export class DownloadService {
    * @returns string a valid CSV string of the input data
    */
   async createCsv(data: any[]): Promise<string> {
-    // Collect all properties because papa only uses the properties of the first object
+    let entityConstructor: any;
+
+    if (data.length > 0 && typeof data[0]?.getConstructor === "function") {
+      entityConstructor = data[0].getConstructor();
+    }
     const keys = new Set<string>();
     data.forEach((row) => Object.keys(row).forEach((key) => keys.add(key)));
 
     data = data.map(transformToReadableFormat);
 
-    return this.papa.unparse(data, {
-      quotes: true,
-      header: true,
-      newline: DownloadService.SEPARATOR_ROW,
-      columns: [...keys],
+    if (!entityConstructor) {
+      return this.papa.unparse(data, {
+        quotes: true,
+        header: true,
+        newline: DownloadService.SEPARATOR_ROW,
+        columns: [...keys],
+      });
+    }
+
+    const result = this.exportFile(data, entityConstructor);
+    return result;
+  }
+
+  exportFile(data: any[], entityConstructor: { schema: any }) {
+    const entitySchema = entityConstructor.schema;
+    const columnLabels = new Map<string, EntitySchemaField>();
+
+    entitySchema.forEach((value: { label: EntitySchemaField }, key: string) => {
+      if (value.label) columnLabels.set(key, value.label);
     });
+
+    const exportEntities = data.map((item) => {
+      let newItem = {};
+      for (const key in item) {
+        if (columnLabels.has(key)) {
+          newItem[key] = item[key];
+        }
+      }
+      return newItem;
+    });
+
+    const columnKeys: string[] = Array.from(columnLabels.keys());
+    const labels: any[] = Array.from(columnLabels.values());
+    const orderedData: any[] = exportEntities.map((item) =>
+      columnKeys.map((key) => item[key]),
+    );
+
+    return this.papa.unparse(
+      {
+        fields: labels,
+        data: orderedData,
+      },
+      {
+        quotes: true,
+        newline: DownloadService.SEPARATOR_ROW,
+      },
+    );
   }
 }