diff --git a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py
index 46c55ab15678962c96310e71e3e6741b1a111ef1..f2e0abc3fc684172065d683c99c1c4309c80d6c0 100644
--- a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py
+++ b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py
@@ -209,10 +209,19 @@ out: union[dict, None]
                 assert len(set(type(entry) for entry in content)) == 1
 
                 if isinstance(content[0], dict):  # all elements are dicts
-                    # An array of objects: must go into exploded sheet
-                    for entry in content:
-                        self._handle_data(data=entry, current_path=path, context=next_context)
-                    continue
+                    # Heuristic to detect enum entries (only id and name):
+                    if all(set(entry.keys()) == {"id", "name"} for entry in content):
+                        # Convert to list of names, do not recurse
+                        content = [entry["name"] for entry in content]
+                    else:
+                        # An array of objects: must go into exploded sheet
+                        for entry in content:
+                            self._handle_data(data=entry, current_path=path, context=next_context)
+                        continue
+            # Heuristic to detect enum entries (dict with only id and name):
+            elif isinstance(content, dict) and set(content.keys()) == {"id", "name"}:
+                content = [content["name"]]
+            # "Normal" dicts
             elif isinstance(content, dict):  # we recurse and simply use the result
                 if not current_path:  # Special handling for top level
                     self._handle_data(content, current_path=path, context=next_context)
@@ -259,7 +268,8 @@ out: union[dict, None]
         sheet = None
         for path_str, value in insertables.items():
             if self._graceful and path_str not in self._sheet_index:
-                warn(f"Ignoring path with missing sheet index: {path_str}")
+                if not (value is None or path_str.endswith(".id") or path_str.endswith(".name")):
+                    warn(f"Ignoring path with missing sheet index: {path_str}")
                 continue
             sheet_meta = self._sheet_index[path_str]
             if sheet is None:
@@ -346,6 +356,7 @@ validation_schema: dict, optional
     if validation_schema is not None:
         validation_schema = array_schema_from_model_schema(read_or_dict(validation_schema))
         try:
+            # FIXME redefine checker for datetime
             validate(data, validation_schema, format_checker=FormatChecker())
         except ValidationError as verr:
             print(verr.message)
diff --git a/src/caosadvancedtools/table_json_conversion/xlsx_utils.py b/src/caosadvancedtools/table_json_conversion/xlsx_utils.py
index 7cedd391087b386c5e0b194301191f2d4881ddf6..5002f3ac7fe4bd78accffe0697cd7ecc7273dc27 100644
--- a/src/caosadvancedtools/table_json_conversion/xlsx_utils.py
+++ b/src/caosadvancedtools/table_json_conversion/xlsx_utils.py
@@ -235,8 +235,6 @@ proper_name: str
         if ii > len(parent):
             parent = foreign_path[:ii]
 
-    # print(data_paths, ii)
-    # breakpoint()
     return parent, data_paths[0][ii]
 
 
diff --git a/unittests/table_json_conversion/test_fill_xlsx.py b/unittests/table_json_conversion/test_fill_xlsx.py
index f580fdbf867f08db0d72ade3537d4f2c1e8301d6..899bb81ef1f91f3326f214f49f135a55b97d299f 100644
--- a/unittests/table_json_conversion/test_fill_xlsx.py
+++ b/unittests/table_json_conversion/test_fill_xlsx.py
@@ -19,6 +19,7 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program. If not, see <https://www.gnu.org/licenses/>.
 
+import datetime
 import json
 import os
 import re
@@ -33,6 +34,7 @@ from caosadvancedtools.table_json_conversion.fill_xlsx import fill_template
 from caosadvancedtools.table_json_conversion.xlsx_utils import (
     get_row_type_column_index,
     get_path_rows,
+    read_or_dict,
 )
 
 from .utils import compare_workbooks
@@ -149,6 +151,32 @@ def test_fill_xlsx():
                      schema=rfp("data/multiple_choice_schema.json"))
 
 
+def test_datetime():
+    """Datetime values from LinkAhead are not serialized as strings."""
+    json_file = rfp("data/simple_data.json")
+    template_file = rfp("data/simple_template.xlsx")
+    known_good = rfp("data/simple_data_datetime.xlsx")
+    # TODO Implement checker for datetime
+    # schema = rfp("data/simple_schema.json")
+
+    # Set datetime explicitly
+    json_data = read_or_dict(json_file)
+    json_data["Training"][0]["date"] = datetime.datetime(2023, 1, 1)
+
+    # Code copied mostly from `fill_and_compare(...)`
+    with tempfile.TemporaryDirectory() as tmpdir:
+        outfile = os.path.join(tmpdir, 'test.xlsx')
+        assert not os.path.exists(outfile)
+        fill_template(data=json_data, template=template_file, result=outfile,
+                      # validation_schema=schema
+                      )
+        assert os.path.exists(outfile)
+        generated = load_workbook(outfile)  # workbook can be read
+
+    known_good_wb = load_workbook(known_good)
+    compare_workbooks(generated, known_good_wb)
+
+
 def test_errors():
     with pytest.raises(AssertionError) as exc:
         fill_and_compare(json_file=rfp("data/error_simple_data.json"),