diff --git a/backend/framework/pom.xml b/backend/framework/pom.xml
index 8d1b25f..aaedccc 100644
--- a/backend/framework/pom.xml
+++ b/backend/framework/pom.xml
@@ -52,6 +52,11 @@
             <artifactId>bcpkix-jdk15on</artifactId>
             <version>1.68</version>
         </dependency>
+        <dependency>
+            <groupId>org.dhatim</groupId>
+            <artifactId>fastexcel</artifactId>
+            <version>0.18.4</version>
+        </dependency>
     </dependencies>
 
 
diff --git a/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/DataView.java b/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/DataView.java
index f2d5e34..be4eb21 100644
--- a/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/DataView.java
+++ b/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/DataView.java
@@ -4,26 +4,18 @@
 import lombok.EqualsAndHashCode;
 import org.jumpserver.chen.framework.console.action.DataViewAction;
 import org.jumpserver.chen.framework.console.component.Logger;
+import org.jumpserver.chen.framework.console.dataview.export.DataExport;
 import org.jumpserver.chen.framework.console.entity.response.SQLResult;
 import org.jumpserver.chen.framework.console.state.DataViewState;
 import org.jumpserver.chen.framework.console.state.StateManager;
-import org.jumpserver.chen.framework.datasource.entity.resource.Field;
 import org.jumpserver.chen.framework.datasource.sql.SQLQueryParams;
 import org.jumpserver.chen.framework.datasource.sql.SQLQueryResult;
 import org.jumpserver.chen.framework.jms.entity.CommandRecord;
 import org.jumpserver.chen.framework.session.SessionManager;
-import org.jumpserver.chen.framework.utils.CodeUtils;
 import org.jumpserver.chen.framework.ws.io.PacketIO;
 
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.sql.Clob;
+import java.io.File;
 import java.sql.SQLException;
-import java.text.SimpleDateFormat;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -74,7 +66,10 @@ public void doAction(DataViewAction action) throws SQLException {
                 this.changeLimit((int) action.getData());
             }
             case DataViewAction.ACTION_EXPORT -> {
-                this.export((String) action.getData());
+                var data = (Map<String, String>) action.getData();
+                var scope = data.get("scope");
+                var format = data.get("format");
+                this.export(scope, format);
             }
         }
     }
@@ -134,84 +129,39 @@ private void fullDataViewData(DataViewData viewData, SQLQueryResult result) {
     }
 
 
-    private static void writeString(BufferedWriter writer, Object object) throws IOException {
-        var str = object.toString();
-
-        if (str.contains(",")) {
-            str = "\"" + str + "\"";
-        }
-        writer.write(str);
-    }
-
-    private void writeCSVData(BufferedWriter writer, DataViewData viewData) throws IOException, SQLException {
-
-        for (Field field : viewData.getFields()) {
-            writeString(writer, field.getName());
-            writer.write(",");
-        }
-        for (Map<String, Object> row : viewData.getData()) {
-            for (Field field : viewData.getFields()) {
-                var obj = row.get(field.getName());
-                if (obj == null) {
-                    writer.write("NULL");
-                    writer.write(",");
-                } else if (obj instanceof Clob clob) {
-                    writer.write(CodeUtils.escapeCsvValue(clob.getSubString(1, (int) clob.length())));
-                    writer.write(",");
-                } else if (obj instanceof Date) {
-                    SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-                    writeString(writer, fmt.format(obj));
-                } else {
-                    writeString(writer, row.get(field.getName()));
-                    writer.write(",");
-                }
-            }
-            writer.newLine();
-        }
-
-        writer.newLine();
-    }
-
-    public void export(String scope) throws SQLException {
+    public void export(String scope, String format) throws SQLException {
         var session = SessionManager.getCurrentSession();
 
-
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
-        String timestamp = LocalDateTime.now().format(formatter);
-        var f = session.createFile(String.format("data_%s.csv", timestamp));
-
         CommandRecord command = new CommandRecord(String.format("Export data: %s", this.title));
 
         try {
             if (!SessionManager.getCurrentSession().canDownload()) {
-                session.getController().sendFile(f.getName());
                 return;
             }
-            var writer = Files.newBufferedWriter(f.toPath());
-
-            if (scope.equals("current")) {
-                this.writeCSVData(writer, this.data);
-                command.setOutput(String.format("%d rows exported", this.data.getData().size()));
-            }
-
-            if (scope.equals("all")) {
-                SQLQueryParams queryParams = new SQLQueryParams();
-                queryParams.setLimit(-1);
-                var result = this.loadDataInterface.loadData(queryParams);
-                var viewData = new DataViewData();
-                this.fullDataViewData(viewData, result);
-                command.setOutput(String.format("%d rows exported", result.getData().size()));
+            File f = null;
+            switch (scope) {
+                case "current":
+                    f = DataExport.export(format, this.data);
+                    command.setOutput(String.format("%d rows exported", this.data.getData().size()));
+                    break;
+                case "all":
+                    SQLQueryParams queryParams = new SQLQueryParams();
+                    queryParams.setLimit(-1);
+                    var result = this.loadDataInterface.loadData(queryParams);
+                    var viewData = new DataViewData();
+                    this.fullDataViewData(viewData, result);
+                    f = DataExport.export(format, viewData);
+                    command.setOutput(String.format("%d rows exported", result.getData().size()));
+                    break;
             }
-            writer.flush();
-            writer.close();
 
             this.consoleLogger.success(command.getOutput());
             session.recordCommand(command);
+            session.getController().sendFile(f.getName());
 
-        } catch (IOException e) {
+        } catch (Exception e) {
             throw new RuntimeException(e);
         }
-        session.getController().sendFile(f.getName());
     }
 
 
diff --git a/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/export/DataExport.java b/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/export/DataExport.java
new file mode 100644
index 0000000..ef71526
--- /dev/null
+++ b/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/export/DataExport.java
@@ -0,0 +1,137 @@
+package org.jumpserver.chen.framework.console.dataview.export;
+
+import org.dhatim.fastexcel.Workbook;
+import org.dhatim.fastexcel.Worksheet;
+import org.jumpserver.chen.framework.console.dataview.DataViewData;
+import org.jumpserver.chen.framework.datasource.entity.resource.Field;
+import org.jumpserver.chen.framework.session.SessionManager;
+import org.jumpserver.chen.framework.utils.CodeUtils;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.sql.Clob;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+
+public class DataExport {
+    public static File export(String format, DataViewData data) throws Exception {
+        var session = SessionManager.getCurrentSession();
+
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
+        String timestamp = LocalDateTime.now().format(formatter);
+
+        String filename = String.format("data_%s", timestamp);
+
+        File f;
+
+        switch (format) {
+            case "excel":
+                f = session.createFile(String.format("%s.xlsx", filename));
+                new DataExportExcel().exportData(f.toPath().toString(), data);
+                break;
+            case "csv":
+                f = session.createFile(String.format("%s.csv", filename));
+                new DataExportCSV().exportData(f.toPath().toString(), data);
+                break;
+            default:
+                throw new Exception("unsupported format: " + format);
+        }
+        return f;
+    }
+}
+
+
+class DataExportExcel implements DataExportInterface {
+    @Override
+    public void exportData(String path, DataViewData data) throws Exception {
+        try (FileOutputStream fos = new FileOutputStream(path);
+             Workbook workbook = new Workbook(fos, "JumpServer", "4.0")) {
+
+            Worksheet sheet = workbook.newWorksheet("Data");
+            List<Field> fields = data.getFields();
+            List<Map<String, Object>> rows = data.getData();
+
+            for (int col = 0; col < fields.size(); col++) {
+                sheet.value(0, col, fields.get(col).getName());
+            }
+
+            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+            for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) {
+                Map<String, Object> row = rows.get(rowIndex);
+
+                for (int col = 0; col < fields.size(); col++) {
+                    Field field = fields.get(col);
+                    Object obj = row.get(field.getName());
+
+                    if (obj == null) {
+                        sheet.value(rowIndex + 1, col, "NULL");
+                    } else if (obj instanceof Clob clob) {
+                        try {
+                            sheet.value(rowIndex + 1, col, clob.getSubString(1, (int) clob.length()));
+                        } catch (Exception e) {
+                            sheet.value(rowIndex + 1, col, "ERROR_CLOB");
+                        }
+                    } else if (obj instanceof Date) {
+                        sheet.value(rowIndex + 1, col, dateFormat.format(obj));
+                    } else {
+                        sheet.value(rowIndex + 1, col, obj.toString());
+                    }
+                }
+            }
+        }
+    }
+}
+
+class DataExportCSV implements DataExportInterface {
+    @Override
+    public void exportData(String path, DataViewData data) throws Exception {
+        var writer = Files.newBufferedWriter(Path.of(path));
+
+        for (Field field : data.getFields()) {
+            writeString(writer, field.getName());
+            writer.write(",");
+        }
+        for (Map<String, Object> row : data.getData()) {
+            for (Field field : data.getFields()) {
+                var obj = row.get(field.getName());
+                if (obj == null) {
+                    writer.write("NULL");
+                    writer.write(",");
+                } else if (obj instanceof Clob clob) {
+                    writer.write(CodeUtils.escapeCsvValue(clob.getSubString(1, (int) clob.length())));
+                    writer.write(",");
+                } else if (obj instanceof Date) {
+                    SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                    writeString(writer, fmt.format(obj));
+                } else {
+                    writeString(writer, row.get(field.getName()));
+                    writer.write(",");
+                }
+            }
+            writer.newLine();
+        }
+
+        writer.newLine();
+        writer.flush();
+        writer.close();
+    }
+
+    private static void writeString(BufferedWriter writer, Object object) throws IOException {
+        var str = object.toString();
+
+        if (str.contains(",")) {
+            str = "\"" + str + "\"";
+        }
+        writer.write(str);
+    }
+}
\ No newline at end of file
diff --git a/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/export/DataExportInterface.java b/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/export/DataExportInterface.java
new file mode 100644
index 0000000..2bfb075
--- /dev/null
+++ b/backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/export/DataExportInterface.java
@@ -0,0 +1,7 @@
+package org.jumpserver.chen.framework.console.dataview.export;
+
+import org.jumpserver.chen.framework.console.dataview.DataViewData;
+
+public interface DataExportInterface {
+    void exportData(String path, DataViewData data) throws Exception;
+}
\ No newline at end of file
diff --git a/frontend/src/components/Main/Explore/DataView/ExportDataDialog.vue b/frontend/src/components/Main/Explore/DataView/ExportDataDialog.vue
index c4029e4..0371bc7 100644
--- a/frontend/src/components/Main/Explore/DataView/ExportDataDialog.vue
+++ b/frontend/src/components/Main/Explore/DataView/ExportDataDialog.vue
@@ -6,8 +6,16 @@
     width="40%"
   >
     <el-form ref="form" :model="form" label-width="80px">
-      <el-radio v-model="form.scope" label="current">{{ $tc('ExportCurrent') }}</el-radio>
-      <el-radio v-model="form.scope" label="all">{{ $tc('ExportAll') }}</el-radio>
+
+      <el-form-item :label="$tc('Scope')">
+        <el-radio v-model="form.scope" label="current">{{ $tc('ExportCurrent') }}</el-radio>
+        <el-radio v-model="form.scope" label="all">{{ $tc('ExportAll') }}</el-radio>
+      </el-form-item>
+
+      <el-form-item :label="$tc('Format')">
+        <el-radio v-model="form.format" label="csv">CSV</el-radio>
+        <el-radio v-model="form.format" label="excel">Excel</el-radio>
+      </el-form-item>
     </el-form>
 
     <span slot="footer" class="dialog-footer">
@@ -35,7 +43,8 @@ export default {
   data() {
     return {
       form: {
-        scope: 'current'
+        scope: 'current',
+        format: 'csv'
       }
     }
   },
@@ -53,7 +62,7 @@ export default {
   },
   methods: {
     onSubmit() {
-      this.$emit('submit', this.form.scope)
+      this.$emit('submit', { scope: this.form.scope, format: this.form.format })
     }
   }
 }