diff --git a/libs/shared/lib/vis/visualizations/tablevis/tablevis.tsx b/libs/shared/lib/vis/visualizations/tablevis/tablevis.tsx
index 82f40a8d8d0ac01a7e6a369f1df79d415ac106fc..873f15a8fc9eeb7ce9d558a836ab4b55485f6b84 100644
--- a/libs/shared/lib/vis/visualizations/tablevis/tablevis.tsx
+++ b/libs/shared/lib/vis/visualizations/tablevis/tablevis.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useMemo, useRef, useState } from 'react';
+import React, { useEffect, useMemo, useRef, useState, forwardRef, useImperativeHandle } from 'react';
 import { Table, AugmentedNodeAttributes } from './components/Table';
 import { VisualizationPropTypes, VISComponentType, VisualizationSettingsPropTypes } from '../../common';
 import { Input } from '@graphpolaris/shared/lib/components/inputs';
@@ -6,6 +6,11 @@ import { SettingsContainer } from '@graphpolaris/shared/lib/vis/components/confi
 import { Button } from '@graphpolaris/shared/lib/components/buttons';
 import { useSearchResultData } from '@graphpolaris/shared/lib/data-access';
 import { EntityPill } from '@graphpolaris/shared/lib/components/pills/Pill';
+import html2canvas from 'html2canvas';
+
+export interface TableVisHandle {
+  exportImageInternal: () => void;
+}
 
 export type TableProps = {
   id: string;
@@ -27,93 +32,114 @@ const settings: TableProps = {
   maxBarsCount: 10,
 };
 
-export const TableVis = ({ data, schema, settings, updateSettings, graphMetadata }: VisualizationPropTypes<TableProps>) => {
-  const searchResults = useSearchResultData();
-  const ref = useRef<HTMLDivElement>(null);
-  useEffect(() => {
-    if (graphMetadata != undefined && settings.displayEntity === '') {
-      if (!graphMetadata.nodes.labels.includes(settings.displayEntity)) {
-        updateSettings({
-          displayEntity: graphMetadata.nodes.labels[0],
-          displayAttributes: Object.keys(graphMetadata.nodes.types[graphMetadata.nodes.labels[0]].attributes),
-        });
+export const TableVis = forwardRef<TableVisHandle, VisualizationPropTypes<TableProps>>(
+  ({ data, schema, settings, updateSettings, graphMetadata }, refExternal) => {
+    const searchResults = useSearchResultData();
+    const ref = useRef<HTMLDivElement>(null);
+    useEffect(() => {
+      if (graphMetadata != undefined && settings.displayEntity === '') {
+        if (!graphMetadata.nodes.labels.includes(settings.displayEntity)) {
+          updateSettings({
+            displayEntity: graphMetadata.nodes.labels[0],
+            displayAttributes: Object.keys(graphMetadata.nodes.types[graphMetadata.nodes.labels[0]].attributes),
+          });
+        }
       }
-    }
-  }, [graphMetadata, data, settings]);
+    }, [graphMetadata, data, settings]);
+
+    const attributesArray = useMemo<AugmentedNodeAttributes[]>(() => {
+      //const similiarityThreshold = 0.9;
+      let displayAttributesSorted: string[];
+
+      displayAttributesSorted = [...settings.displayAttributes].sort((a, b) => a.localeCompare(b));
 
-  const attributesArray = useMemo<AugmentedNodeAttributes[]>(() => {
-    //const similiarityThreshold = 0.9;
-    let displayAttributesSorted: string[];
+      const dataNodes = (searchResults?.nodes?.length ?? 0) === 0 ? data.nodes : searchResults.nodes;
 
-    displayAttributesSorted = [...settings.displayAttributes].sort((a, b) => a.localeCompare(b));
+      return (
+        dataNodes
+          .filter((node) => {
+            // some dataset do not have label field
+            let labelNode = '';
+            if (node.label !== undefined) {
+              labelNode = node.label;
+            } else {
+              const idParts = node._id.split('/');
+              labelNode = idParts[0];
+            }
+            return labelNode === settings.displayEntity;
+          })
+          ///.filter((obj) => obj.similarity === undefined || obj.similarity >= similiarityThreshold)
+          .map((node) => {
+            // get attributes filtered and sorted
+            const filteredAttributes = Object.fromEntries(
+              Object.entries(node.attributes)
+                .filter(([attr]) => settings.displayAttributes.includes(attr))
+                .sort(([attrA], [attrB]) => settings.displayAttributes.indexOf(attrA) - settings.displayAttributes.indexOf(attrB)),
+            );
 
-    const dataNodes = (searchResults?.nodes?.length ?? 0) === 0 ? data.nodes : searchResults.nodes;
+            // doubled types structure to handle discrepancies in schema object in sb and dev env.
+
+            let types =
+              schema.nodes.find((n: any) => {
+                let labelNode = node.label;
+                return labelNode === n.key;
+              })?.attributes?.attributes ??
+              schema.nodes.find((n: any) => {
+                let labelNode = node.label;
+
+                return labelNode === n.name;
+              })?.attributes;
+
+            if (types) {
+              return {
+                attribute: filteredAttributes,
+                type: Object.fromEntries(types.map((t: any) => [t.name, t.type])),
+              };
+            } else {
+              return {
+                attribute: filteredAttributes,
+                type: {},
+              };
+            }
+          })
+      );
+    }, [data.nodes, settings.displayEntity, settings.displayAttributes, searchResults]);
+
+    const exportImageInternal = () => {
+      if (ref.current) {
+        // Check if divRef.current is not null
+        html2canvas(ref.current).then((canvas) => {
+          const pngData = canvas.toDataURL('image/png');
+          const a = document.createElement('a');
+          a.href = pngData;
+          a.download = 'tablevis.png';
+          a.click();
+        });
+      } else {
+        console.error('The referenced div is null.');
+      }
+    };
+
+    useImperativeHandle(refExternal, () => ({
+      exportImageInternal,
+    }));
 
     return (
-      dataNodes
-        .filter((node) => {
-          // some dataset do not have label field
-          let labelNode = '';
-          if (node.label !== undefined) {
-            labelNode = node.label;
-          } else {
-            const idParts = node._id.split('/');
-            labelNode = idParts[0];
-          }
-          return labelNode === settings.displayEntity;
-        })
-        ///.filter((obj) => obj.similarity === undefined || obj.similarity >= similiarityThreshold)
-        .map((node) => {
-          // get attributes filtered and sorted
-          const filteredAttributes = Object.fromEntries(
-            Object.entries(node.attributes)
-              .filter(([attr]) => settings.displayAttributes.includes(attr))
-              .sort(([attrA], [attrB]) => settings.displayAttributes.indexOf(attrA) - settings.displayAttributes.indexOf(attrB)),
-          );
-
-          // doubled types structure to handle discrepancies in schema object in sb and dev env.
-
-          let types =
-            schema.nodes.find((n: any) => {
-              let labelNode = node.label;
-              return labelNode === n.key;
-            })?.attributes?.attributes ??
-            schema.nodes.find((n: any) => {
-              let labelNode = node.label;
-
-              return labelNode === n.name;
-            })?.attributes;
-
-          if (types) {
-            return {
-              attribute: filteredAttributes,
-              type: Object.fromEntries(types.map((t: any) => [t.name, t.type])),
-            };
-          } else {
-            return {
-              attribute: filteredAttributes,
-              type: {},
-            };
-          }
-        })
+      <div className="h-full w-full" ref={ref}>
+        {attributesArray.length > 0 && (
+          <Table
+            data={attributesArray}
+            itemsPerPage={settings.itemsPerPage}
+            showBarPlot={settings.showBarplot}
+            showAttributes={settings.displayAttributes}
+            selectedEntity={settings.displayEntity}
+            maxBarsCount={settings.maxBarsCount}
+          />
+        )}
+      </div>
     );
-  }, [data.nodes, settings.displayEntity, settings.displayAttributes, searchResults]);
-
-  return (
-    <div className="h-full w-full" ref={ref}>
-      {attributesArray.length > 0 && (
-        <Table
-          data={attributesArray}
-          itemsPerPage={settings.itemsPerPage}
-          showBarPlot={settings.showBarplot}
-          showAttributes={settings.displayAttributes}
-          selectedEntity={settings.displayEntity}
-          maxBarsCount={settings.maxBarsCount}
-        />
-      )}
-    </div>
-  );
-};
+  },
+);
 
 const TableSettings = ({ settings, graphMetadata, updateSettings }: VisualizationSettingsPropTypes<TableProps>) => {
   useEffect(() => {
@@ -218,15 +244,20 @@ const TableSettings = ({ settings, graphMetadata, updateSettings }: Visualizatio
     </SettingsContainer>
   );
 };
+const tableRef = React.createRef<{ exportImageInternal: () => void }>();
 
 export const TableComponent: VISComponentType<TableProps> = {
   displayName: 'TableVis',
   description: 'Node Attribute Statistics and Details',
-  component: TableVis,
+  component: React.forwardRef((props: VisualizationPropTypes<TableProps>, ref) => <TableVis {...props} ref={tableRef} />),
   settingsComponent: TableSettings,
   settings: settings,
   exportImage: () => {
-    alert('Not yet supported');
+    if (tableRef.current) {
+      tableRef.current.exportImageInternal();
+    } else {
+      console.error('Map reference is not set.');
+    }
   },
 };