diff --git a/src/icons/svg/zip.svg b/src/icons/svg/zip.svg
new file mode 100644
index 0000000000000000000000000000000000000000..e9a9d012d3f6711b7599480f06d6ebc2809ff99d
--- /dev/null
+++ b/src/icons/svg/zip.svg
@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506326020470" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2561" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M619.364365 933.396352c1.372783 0.06385 2.681715 0.191551 4.054497 0.191551h309.291099a65.670086 65.670086 0 0 0 65.606235-65.606235V150.974154a65.670086 65.670086 0 0 0-65.606235-65.606235H623.418862c-1.372783 0-2.71364 0.127701-4.054497 0.191551V-0.031925L15.691224 80.547217v858.404116l603.673141 82.654279v-88.20926z m0-810.101325c1.340857-0.191551 2.681715-0.415027 4.054497-0.415027h309.291099c15.515635 0 28.12608 12.610444 28.12608 28.12608v717.007513a28.158005 28.158005 0 0 1-28.12608 28.12608H623.418862c-1.372783 0-2.71364-0.223476-4.054497-0.415028V123.326952zM248.329977 605.429026l-143.918691-3.671395v-23.401154l86.868402-133.255682v-1.181231l-78.919033 1.308932v-36.043523l134.564614-3.51177v26.082869l-87.506906 133.734559v1.149307l88.911614 1.404707v37.352456z m72.406297 1.85166l-44.759096-1.149306v-201.192456l44.759096-1.149306v203.491068z m171.087015-92.966111c-16.664942 15.356009-41.151551 22.060296-69.341481 21.868745a113.81325 113.81325 0 0 1-16.122213-1.05353v74.353733l-46.099954-1.181231v-202.788714c14.238628-2.809415 34.383414-5.171878 63.179923-5.938083 29.498862-0.766204 50.792954 4.309899 65.191208 15.292159 13.887451 10.439532 23.305378 27.966454 23.305378 48.845518s-7.119314 38.629462-20.080936 50.601403z m-65.925487-79.174435a80.13219 80.13219 0 0 0-19.538207 2.202837v61.392113c4.022572 0.92583 8.970974 1.213157 15.834887 1.213156 25.380514-0.031925 41.215401-12.897771 41.215401-34.479189 0-19.378581-13.63205-30.712019-37.480156-30.296992z m306.322058-296.233702h73.523679v30.328917h-73.523679v-30.328917z m-73.555604 45.397599h73.523679v30.360842h-73.523679v-30.360842z m73.555604 49.675573h73.523679v30.360842h-73.523679v-30.360842z m0 95.903227h73.523679v30.328917h-73.523679v-30.328917z m-73.555604-48.717818h73.523679v30.328917h-73.523679v-30.328917z m72.821325 376.142417a72.7894 72.7894 0 0 0 72.7894-72.821325l-13.440499-121.986095c0-40.225721-19.155105-72.821325-59.380827-72.821325s-59.348901 32.595604-59.348901 72.821325l-13.472424 121.986095a72.7894 72.7894 0 0 0 72.821325 72.821325z m-24.103508-133.862261h48.207015v101.84131h-48.207015v-101.84131z" p-id="2562"></path></svg>
diff --git a/src/router/index.js b/src/router/index.js
index a705a736b5ebe3884552ff60df37db582cf5f887..b50c742624b2dd39b5c0f7494c3add2d9df51481 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -154,6 +154,17 @@ export const asyncRouterMap = [
       { path: 'upload', component: _import('excel/uploadExcel'), name: 'upload excel' }
     ]
   },
+  {
+    path: '/zip',
+    component: Layout,
+    redirect: '/zip/download',
+    name: 'zip',
+    icon: 'zip',
+    children: [
+      { path: 'download', component: _import('zip/index'), name: '导出zip' },
+      { path: 'download2', component: _import('zip/select'), name: '导出已选择项' }
+    ]
+  },
   {
     path: '/theme',
     component: Layout,
diff --git a/src/views/zip/index.vue b/src/views/zip/index.vue
new file mode 100644
index 0000000000000000000000000000000000000000..fa32a9832fe75206977a1b7a1382debc62879cd1
--- /dev/null
+++ b/src/views/zip/index.vue
@@ -0,0 +1,74 @@
+<template>
+  <div class="app-container">
+    <el-button style='margin-bottom:20px;' type="primary" icon="document" @click="handleDownload" :loading="downloadLoading">导出zip</el-button>
+    <el-table :data="list" v-loading.body="listLoading" element-loading-text="拼命加载中" border fit highlight-current-row>
+      <el-table-column align="center" label='ID' width="95">
+        <template scope="scope">
+          {{scope.$index}}
+        </template>
+      </el-table-column>
+      <el-table-column label="文章标题">
+        <template scope="scope">
+          {{scope.row.title}}
+        </template>
+      </el-table-column>
+      <el-table-column label="作者" width="95" align="center">
+        <template scope="scope">
+          <el-tag>{{scope.row.author}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="阅读数" width="115" align="center">
+        <template scope="scope">
+          {{scope.row.pageviews}}
+        </template>
+      </el-table-column>
+      <el-table-column align="center" prop="created_at" label="发布时间" width="220">
+        <template scope="scope">
+          <i class="el-icon-time"></i>
+          <span>{{scope.row.display_time}}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import { fetchList } from '@/api/article'
+
+export default {
+  data() {
+    return {
+      list: null,
+      listLoading: true,
+      downloadLoading: false
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  methods: {
+    fetchData() {
+      this.listLoading = true
+      fetchList().then(response => {
+        this.list = response.data.items
+        this.listLoading = false
+      })
+    },
+    handleDownload() {
+      this.downloadLoading = true
+      require.ensure([], () => {
+        const { export_txt_to_zip } = require('vendor/Export2Zip')
+        const tHeader = ['序号', '文章标题', '作者', '阅读数', '发布时间']
+        const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
+        const list = this.list
+        const data = this.formatJson(filterVal, list)
+        export_txt_to_zip(tHeader, data, '列表文本', '压缩文本')
+        this.downloadLoading = false
+      })
+    },
+    formatJson(filterVal, jsonData) {
+      return jsonData.map(v => filterVal.map(j => v[j]))
+    }
+  }
+}
+</script>
diff --git a/src/views/zip/select.vue b/src/views/zip/select.vue
new file mode 100644
index 0000000000000000000000000000000000000000..fc4ac7fb27eba4eac439dc3640502a266ab8dfa8
--- /dev/null
+++ b/src/views/zip/select.vue
@@ -0,0 +1,88 @@
+<template>
+  <div class="app-container">
+    <el-button style='margin-bottom:20px' type="primary" icon="document" @click="handleDownload" :loading="downloadLoading">导出已选择项</el-button>
+    <el-table :data="list" v-loading.body="listLoading" element-loading-text="拼命加载中" border fit highlight-current-row @selection-change="handleSelectionChange"
+      ref="multipleTable">
+      <el-table-column type="selection" align="center"></el-table-column>
+      <el-table-column align="center" label='ID' width="95">
+        <template scope="scope">
+          {{scope.$index}}
+        </template>
+      </el-table-column>
+      <el-table-column label="文章标题">
+        <template scope="scope">
+          {{scope.row.title}}
+        </template>
+      </el-table-column>
+      <el-table-column label="作者" width="95" align="center">
+        <template scope="scope">
+          <el-tag>{{scope.row.author}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="阅读数" width="115" align="center">
+        <template scope="scope">
+          {{scope.row.pageviews}}
+        </template>
+      </el-table-column>
+      <el-table-column align="center" prop="created_at" label="发布时间" width="220">
+        <template scope="scope">
+          <i class="el-icon-time"></i>
+          <span>{{scope.row.display_time}}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import { fetchList } from '@/api/article'
+
+export default {
+  data() {
+    return {
+      list: null,
+      listLoading: true,
+      multipleSelection: [],
+      downloadLoading: false
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  methods: {
+    fetchData() {
+      this.listLoading = true
+      fetchList(this.listQuery).then(response => {
+        this.list = response.data.items
+        this.listLoading = false
+      })
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    handleDownload() {
+      if (this.multipleSelection.length) {
+        this.downloadLoading = true
+        require.ensure([], () => {
+          const { export_txt_to_zip } = require('vendor/Export2Zip')
+          const tHeader = ['序号', '文章标题', '作者', '阅读数', '发布时间']
+          const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
+          const list = this.multipleSelection
+          const data = this.formatJson(filterVal, list)
+          export_txt_to_zip(tHeader, data, '列表文本', '压缩文本')
+          this.$refs.multipleTable.clearSelection()
+          this.downloadLoading = false
+        })
+      } else {
+        this.$message({
+          message: '请至少选择一条记录',
+          type: 'warning'
+        })
+      }
+    },
+    formatJson(filterVal, jsonData) {
+      return jsonData.map(v => filterVal.map(j => v[j]))
+    }
+  }
+}
+</script>