vue中上傳excel并在線(json)編輯

上傳excel文件鲸伴,通過xlsx將文件轉(zhuǎn)為json,json文件通過codemirror(vue2版本)在線編輯航邢,編輯后的文件替換第一次上傳的文件

20230314_160827.gif

安裝組件

1.安裝xlsx
"xlsx": "^0.18.5"
2.安裝vue-codemirror
"codemirror": "^5.46.0"
"vue-codemirror": "^4.0.6"

步驟流程

1.上傳excel文件
2.excel文件通過xlxs組件轉(zhuǎn)為json
3.json文件在線展示并編輯
4.將編輯后的json文件在生成file上傳替換

部分代碼

1、文件上傳笛丙,使用element-ui上傳組件
<el-upload
        class="upload-demo"
          drag
          :action="actionUrl"
          :on-success="handleSuccess"
          :before-upload="beforeUpload"
          :on-remove="handleRemove"
          :limit="1"
          :file-list="fileList"
          :on-preview="handlePreview"
          accept=".xls, .xlsx"
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">
            <em>點擊</em> 或?qū)⑽募献У竭@里上傳
          </div>
        </el-upload>
2嫉鲸、點擊預(yù)覽
handlePreview(row) {
      this.codeMirrorVisible = true;
      this.$nextTick(() => {
        this.$refs.codeMirror.url = row.url;  // 文件url
        this.$refs.codeMirror.fileName = row.name; // 文件name
        this.$refs.codeMirror.init(); 
      })
    },
3、彈框顯示(在線編輯json組件)
// appendToBody屬性可不寫棵磷,解決兩個dialog彈框疊加账阻,詳情查看element-ui文檔
// 引用方式不寫了,就import xxx 的泽本,懂得都懂淘太,code-mirror組件代碼在下面
<code-mirror v-if="codeMirrorVisible" ref="codeMirror" :appendToBody="true" @changeFile="changeFile" />
// @changeFile回調(diào)修改fileList,就是將上傳文件替換下
changeFile(data) {
      this.fileList = [{
        name: data.name, // 文件name,自行修改
        url: `${window.SITE_CONFIG["downloadURL"]}/${data.id}` // 文件url,自行修改
      }]
    },
4蒲牧、在線編輯彈框(組件code-mirror代碼)
<template>
  <el-dialog
    :visible.sync="visible"
    title="在線編輯"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :append-to-body="appendToBody"
    width="800px"
  >
    <commonEditor :value="value" language="javescript" @input="change"></commonEditor>
    <template slot="footer">
      <el-button size="small" @click="visible = false">取消</el-button>
      <el-button type="primary" size="small" @click="dataFormSubmitHandle()">確認</el-button>
    </template>
  </el-dialog>
</template>

<script>
import Cookies from "js-cookie";  // 可以刪除
import commonEditor from "@/components/common-editor.vue";
import * as XLSX from "xlsx/xlsx.mjs";
export default {
  props: ["appendToBody"],
  components: { commonEditor },
  data() {
    return {
      actionUrl: `${window.SITE_CONFIG["uploadURL"]}?token=${Cookies.get(
        "token"
      )}`, // 修改成個人接收file文件地址
      visible: false,
      url: "",
      fileName: "",
      value: "",
      changeInput: ""
    };
  },
  methods: {
    init() {
      this.visible = true;
      // 將在線文件轉(zhuǎn)為json
      // this.url 就是上面2中的this.$refs.codeMirror.url = row.url;  // 文件url
      this.$http.get(this.url, { responseType: "arraybuffer" }).then(res => {
        const data = new Uint8Array(res.data);
        let workbook = XLSX.read(data, { type: "array" });
        let firstSheetName = workbook.SheetNames[0];
        let worksheet = workbook.Sheets[firstSheetName];
        this.value = XLSX.utils.sheet_to_json(worksheet);
      });
    },
    change(value) {
      this.changeInput = value;
    },
    // 點擊確認撇贺,將修改后的json,轉(zhuǎn)為blob冰抢,再轉(zhuǎn)為file,(也可以直接導出file)
    dataFormSubmitHandle() {
      const ws = XLSX.utils.json_to_sheet(JSON.parse(this.changeInput));
      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
      // const file = XLSX.writeFile(wb, this.fileName); // 直接瀏覽器導出excel文件
      // 將文件轉(zhuǎn)為file重新上傳
      const wbout = XLSX.write(wb, {
        bookType: "xlsx",
        bookSST: true,
        type: "array"
      });
      const blob = new Blob([wbout], {
        type: "application/octet-stream;charset=utf-8"
      });
      const file = new File([blob], this.fileName, { type: "xls/xlsx" });
      const fileParams = new FormData();
      fileParams.append("file", file);
      this.$http
        .post(this.actionUrl, fileParams, {
          headers: {
            "Content-Type": "multipart/form-data"
          }
        })
        .then(({ data: res }) => {
          if (res.code != 0) {
            return this.$message.er;
          }
          this.$emit("changeFile", res.data); // 替換文件
          this.visible = false;
        });
    }
  }
};
</script>

<style>
</style>
5松嘶、vue-codemirror(組件commonEditor代碼)
<template>
  <div class="json-editor">
    <textarea ref="textarea" />
  </div>
</template>

<script>
import CodeMirror from "codemirror";
import "codemirror/addon/lint/lint.css";
import "codemirror/lib/codemirror.css";
import "codemirror/theme/panda-syntax.css";
import "codemirror/mode/javascript/javascript";
import "codemirror/addon/lint/json-lint";
// 折疊代碼
import "codemirror/addon/fold/foldgutter.css";
import "codemirror/addon/fold/foldcode.js";
import "codemirror/addon/fold/foldgutter.js";
import "codemirror/addon/fold/brace-fold.js";
import "codemirror/addon/fold/xml-fold.js";
import "codemirror/addon/fold/indent-fold.js";
import "codemirror/addon/fold/markdown-fold.js";
import "codemirror/addon/fold/comment-fold.js";

export default {
  props: ["value"],
  data() {
    return {
      jsonEditor: null
    };
  },
  watch: {
    value(value) {
      const editor_value = this.jsonEditor.getValue();
      if (value !== editor_value) {
        this.jsonEditor.setValue(JSON.stringify(this.value, null, 2));
      }
    }
  },
  mounted() {
    this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, {
      lineNumbers: true,
      mode: "application/json",
      gutters: [
        "CodeMirror-lint-markers",
        "CodeMirror-linenumbers",
        "CodeMirror-foldgutter"
      ],
      theme: "panda-syntax",
      lint: true,
      foldGutter: {
        rangeFinder: new CodeMirror.fold.combine(
          CodeMirror.fold.indent,
          CodeMirror.fold.comment
        )
      }
    });

    this.jsonEditor.setValue(JSON.stringify(this.value, null, 2));
    this.jsonEditor.on("change", cm => {
      this.$emit("changed", cm.getValue());
      this.$emit('input', cm.getValue())
    });
  }
};
</script>

<style lang="scss" scoped>
.json-editor {
  max-height: 500px;
  overflow: auto;
  position: relative;
  ::v-deep.CodeMirror {
    height: auto;
    min-height: 180px;
  }
  ::v-deep.CodeMirror-scroll {
    min-height: 180px;
  }
  ::v-deep.cm-s-rubyblue span.cm-string {
    color: #f08047;
  }
}
</style>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市挎扰,隨后出現(xiàn)的幾起案子翠订,更是在濱河造成了極大的恐慌,老刑警劉巖遵倦,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尽超,死亡現(xiàn)場離奇詭異,居然都是意外死亡梧躺,警方通過查閱死者的電腦和手機似谁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掠哥,“玉大人巩踏,你說我怎么就攤上這事⌒螅” “怎么了塞琼?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長禁舷。 經(jīng)常有香客問我彪杉,道長,這世上最難降的妖魔是什么榛了? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任在讶,我火速辦了婚禮,結(jié)果婚禮上霜大,老公的妹妹穿的比我還像新娘构哺。我一直安慰自己,他們只是感情好战坤,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布曙强。 她就那樣靜靜地躺著,像睡著了一般途茫。 火紅的嫁衣襯著肌膚如雪碟嘴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天囊卜,我揣著相機與錄音娜扇,去河邊找鬼错沃。 笑死,一個胖子當著我的面吹牛雀瓢,可吹牛的內(nèi)容都是我干的枢析。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼刃麸,長吁一口氣:“原來是場噩夢啊……” “哼醒叁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起泊业,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤把沼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吁伺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饮睬,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年箱蝠,在試婚紗的時候發(fā)現(xiàn)自己被綠了续捂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垦垂。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡宦搬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出劫拗,到底是詐尸還是另有隱情间校,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布页慷,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏呜象。R本人自食惡果不足惜轨淌,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望州袒。 院中可真熱鬧揭绑,春花似錦、人聲如沸郎哭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夸研。三九已至邦蜜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亥至,已是汗流浹背悼沈。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工贱迟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人絮供。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓关筒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親杯缺。 傳聞我的和親對象是個殘疾皇子蒸播,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容