diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/EntitiesFinder.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/EntitiesFinder.java
index f875a5ea8ed81951b88ab98181516a54d82ce9ca..691d890b683f3e5e12e2d7c3420a5b72d3e635f2 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/EntitiesFinder.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/EntitiesFinder.java
@@ -139,7 +139,7 @@ class EntitiesFinder
         final List<DataSetPermId> dataSetPermIds = permIds.stream().map(DataSetPermId::new)
                 .collect(Collectors.toList());
         final DataSetFetchOptions fetchOptions = new DataSetFetchOptions();
-
+        fetchOptions.withSampleProperties();
         configureFetchOptions(fetchOptions);
         configureFetchOptions(fetchOptions.withParents());
         configureFetchOptions(fetchOptions.withChildren());
@@ -217,6 +217,7 @@ class EntitiesFinder
         final List<SamplePermId> samplePermIds = permIds.stream().map(SamplePermId::new)
                 .collect(Collectors.toList());
         final SampleFetchOptions fetchOptions = new SampleFetchOptions();
+        fetchOptions.withSampleProperties();
         configureFetchOptions(fetchOptions);
         configureFetchOptions(fetchOptions.withParents());
         configureFetchOptions(fetchOptions.withChildren());
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/ExportExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/ExportExecutor.java
index 7e1785f49a15a1bd580e5a50d34dfda8d3c63cb4..2ef51e1ef1ff568e0dfc9d73fccaab946f7e4c8b 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/ExportExecutor.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/ExportExecutor.java
@@ -62,6 +62,7 @@ import java.util.Collection;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.EnumSet;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -1172,7 +1173,6 @@ public class ExportExecutor implements IExportExecutor
                 }
             }, "NotoEmoji");
 
-            //String replacedHtml = html.replaceAll(XML_10_REGEXP, "").replaceAll(UNPRINTABLE_CHARACTER_REFERENCES_REGEXP, "");
             String replacedHtml = ExportPDFUtils.addStyleHeader(html);
             replacedHtml = ExportPDFUtils.replaceHSLToHex(replacedHtml, "color", ExportPDFUtils.hslColorPattern);
             replacedHtml = ExportPDFUtils.insertPagePagebreak(replacedHtml, "<h2>Identification Info</h2>");
@@ -1477,7 +1477,7 @@ public class ExportExecutor implements IExportExecutor
             final List<PropertyAssignment> propertyAssignments = typeObj.getPropertyAssignments();
             if (propertyAssignments != null)
             {
-                final Map<String, Serializable> properties = ((IPropertiesHolder) entityObj).getProperties();
+                final Map<String, Serializable> properties = getMergedProperties((IPropertiesHolder) entityObj);
                 for (final PropertyAssignment propertyAssignment : propertyAssignments)
                 {
                     System.out.println(selectedExportFields);
@@ -1488,10 +1488,25 @@ public class ExportExecutor implements IExportExecutor
 
                     if (rawPropertyValue != null && allowsValue(selectedExportProperties, propertyTypeCode))
                     {
-                        final String initialPropertyValue = String.valueOf(rawPropertyValue);
+                        final String initialPropertyValue = String.valueOf(rawPropertyValue instanceof Sample
+                                ? ((Sample) rawPropertyValue).getIdentifier().getIdentifier()
+                                : rawPropertyValue);
                         final String propertyValue;
 
-                        if (propertyType.getDataType() == DataType.MULTILINE_VARCHAR &&
+                        if (propertyType.getDataType() == DataType.SAMPLE)
+                        {
+                            if (rawPropertyValue instanceof Sample[])
+                            {
+                                propertyValue = Arrays.stream(((Sample[]) rawPropertyValue)).map(sample -> sample.getIdentifier().getIdentifier())
+                                        .collect(Collectors.joining(", "));
+                            } else if (rawPropertyValue instanceof Sample)
+                            {
+                                propertyValue = ((Sample) rawPropertyValue).getIdentifier().getIdentifier();
+                            } else
+                            {
+                                throw new IllegalArgumentException("Sample property value is not of type Sample or Sample[].");
+                            }
+                        } else if (propertyType.getDataType() == DataType.MULTILINE_VARCHAR &&
                                 Objects.equals(propertyType.getMetaData().get("custom_widget"), "Word Processor"))
                         {
                             propertyValue = encodeImages(initialPropertyValue);
@@ -1965,6 +1980,32 @@ public class ExportExecutor implements IExportExecutor
         }
     }
 
+    private static Map<String, Serializable> getMergedProperties(final IPropertiesHolder entity)
+    {
+        final Map<String, Sample[]> sampleProperties;
+        if (entity instanceof Sample)
+        {
+            sampleProperties = ((Sample) entity).getSampleProperties();
+        } else if (entity instanceof Experiment)
+        {
+            sampleProperties = ((Experiment) entity).getSampleProperties();
+        } else if (entity instanceof DataSet)
+        {
+            sampleProperties = ((DataSet) entity).getSampleProperties();
+        } else
+        {
+            sampleProperties = null;
+        }
+
+        final Map<String, Serializable> properties = new HashMap<>(entity.getProperties());
+        if (sampleProperties != null)
+        {
+            properties.putAll(sampleProperties);
+        }
+
+        return properties;
+    }
+
     private static class EntitiesVo
     {
 
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSEntityExportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSEntityExportHelper.java
index fbe8820d4856a49adc099aaee695d8ae769334de..4745b15de428d791e1947e684a3209382fe77cee 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSEntityExportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSEntityExportHelper.java
@@ -231,7 +231,7 @@ public abstract class AbstractXLSEntityExportHelper<ENTITY extends IPermIdHolder
         return new AdditionResult(rowNumber, warnings, valueFiles, miscellaneousFiles);
     }
 
-    private static <ENTITY extends IPermIdHolder & IPropertiesHolder> Map<String, Serializable> getMergedProperties(final ENTITY entity)
+    private static Map<String, Serializable> getMergedProperties(final IPropertiesHolder entity)
     {
         final Map<String, Sample[]> sampleProperties;
         if (entity instanceof Sample)