diff --git a/server/admin/api_set_audit.go b/server/admin/api_set_audit.go
index 465f9cf..872c7a6 100644
--- a/server/admin/api_set_audit.go
+++ b/server/admin/api_set_audit.go
@@ -5,6 +5,7 @@ import (
 	"strconv"
 
 	"github.com/bjdgyc/anylink/dbdata"
+	"github.com/gocarina/gocsv"
 )
 
 func SetAuditList(w http.ResponseWriter, r *http.Request) {
@@ -29,3 +30,24 @@ func SetAuditList(w http.ResponseWriter, r *http.Request) {
 
 	RespSucess(w, data)
 }
+
+func SetAuditExport(w http.ResponseWriter, r *http.Request) {
+	var datas []dbdata.AccessAudit
+	maxNum := 1000000
+	session := dbdata.GetAuditSession(r.FormValue("search"))
+	count, err := dbdata.FindAndCount(session, &datas, maxNum, 0)
+	if err != nil && !dbdata.CheckErrNotFound(err) {
+		RespError(w, RespInternalErr, err)
+		return
+	}
+	if count == 0 {
+		RespError(w, RespParamErr, "你导出的总数量为0条,请调整搜索条件,再导出")
+		return
+	}
+	if count > int64(maxNum) {
+		RespError(w, RespParamErr, "你导出的数据量超过100万条,请调整搜索条件,再导出")
+		return
+	}
+	gocsv.Marshal(datas, w)
+
+}
diff --git a/server/admin/server.go b/server/admin/server.go
index 75b6ac9..807efbd 100644
--- a/server/admin/server.go
+++ b/server/admin/server.go
@@ -39,6 +39,7 @@ func StartAdmin() {
 	r.HandleFunc("/set/other/smtp", SetOtherSmtp)
 	r.HandleFunc("/set/other/smtp/edit", SetOtherSmtpEdit)
 	r.HandleFunc("/set/audit/list", SetAuditList)
+	r.HandleFunc("/set/audit/export", SetAuditExport)
 
 	r.HandleFunc("/user/list", UserList)
 	r.HandleFunc("/user/detail", UserDetail)
diff --git a/server/go.mod b/server/go.mod
index 55df247..7065a25 100644
--- a/server/go.mod
+++ b/server/go.mod
@@ -7,6 +7,7 @@ require (
 	github.com/go-ldap/ldap v3.0.3+incompatible // indirect
 	github.com/go-ldap/ldap/v3 v3.4.3 // indirect
 	github.com/go-sql-driver/mysql v1.6.0
+	github.com/gocarina/gocsv v0.0.0-20220712153207-8b2118da4570 // indirect
 	github.com/golang-jwt/jwt/v4 v4.0.0
 	github.com/google/gopacket v1.1.19
 	github.com/gorilla/mux v1.8.0
diff --git a/web/src/pages/set/Audit.vue b/web/src/pages/set/Audit.vue
index 1740881..bbad51e 100644
--- a/web/src/pages/set/Audit.vue
+++ b/web/src/pages/set/Audit.vue
@@ -48,6 +48,11 @@
               icon="el-icon-refresh"
               @click="rest">重置搜索
           </el-button>
+          <el-button
+              size="small"
+              icon="el-icon-download"
+              @click="handleExport">导出
+          </el-button>          
         </el-form-item>
         </div>
       </el-form>
@@ -55,6 +60,9 @@
       <el-table
           ref="multipleTable"
           :data="tableData"
+          v-loading="loading"
+          element-loading-text="玩命搜索中"
+          element-loading-spinner="el-icon-loading"
           border>
 
         <el-table-column
@@ -171,6 +179,7 @@ export default {
             { text: 'HTTPS', value: '3' },
             { text: 'HTTP', value: '4' },
       ],
+      loading: false,
       rules: {
         username: [
           {max: 30, message: '长度小于 30 个字符', trigger: 'blur'}
@@ -204,6 +213,7 @@ export default {
         }
     },        
     getData(p) {
+      this.loading = true
       if (! this.searchForm.date) {
         this.searchForm.date = ["", ""];
       }        
@@ -217,6 +227,7 @@ export default {
         console.log(data);
         this.tableData = data.datas;
         this.count = data.count
+        this.loading = false
       }).catch(error => {
         this.$message.error('哦,请求出错');
         console.log(error);
@@ -241,6 +252,45 @@ export default {
         console.log(error);
       });
     },
+    handleExport() {
+      if (! this.searchForm.date) {
+        this.searchForm.date = ["", ""];
+      }
+      const exporting = this.$loading({
+            lock: true,
+            text: '玩命导出中,请稍等片刻...',
+            spinner: 'el-icon-loading',
+            background: 'rgba(0, 0, 0, 0.7)'
+      });
+      axios.get('/set/audit/export', {
+        params: {
+          search: this.searchForm,
+        }
+      }).then(resp => {
+        var rdata = resp.data
+        if (rdata.code && rdata.code != 0) {
+            exporting.close();
+            this.$message.error(rdata.msg);
+            return ;
+        }
+        exporting.close();
+        this.$message.success("成功导出CSV文件")
+        let csvData = 'data:text/csv;charset=utf-8,\uFEFF' + rdata
+        this.createDownLoadClick(csvData, `anylink_audit_log_` + Date.parse(new Date()) + `.csv`)
+      }).catch(error => {
+        exporting.close();
+        this.$message.error('哦,请求出错');
+        console.log(error);
+      });
+    },
+    createDownLoadClick(content, fileName) {
+        const link = document.createElement('a')
+        link.href = encodeURI(content)
+        link.download = fileName
+        document.body.appendChild(link)
+        link.click()
+        document.body.removeChild(link)
+    },    
     protoFormat(row) {
         var access_proto = row.access_proto
         if (row.access_proto == 0) {