From e888346ebcd8e3e099a15c7edd7bf367c057193a Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期二, 04 三月 2025 15:33:33 +0800
Subject: [PATCH] Merge branch 'refs/heads/dev'

---
 src/components/Preview/filePreview.vue |  230 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 230 insertions(+), 0 deletions(-)

diff --git a/src/components/Preview/filePreview.vue b/src/components/Preview/filePreview.vue
new file mode 100644
index 0000000..df7299b
--- /dev/null
+++ b/src/components/Preview/filePreview.vue
@@ -0,0 +1,230 @@
+<template>
+  <div>
+    <div v-if="isImage">
+      <img :src="imgUrl" alt="Image Preview" />
+    </div>
+    <div v-if="isPdf">
+      <object :data="fileUrl" type="application/pdf" width="100%" height="750px">
+        <p>鎮ㄧ殑娴忚鍣ㄤ笉鏀寔 PDF 棰勮銆�<a :href="fileUrl" style="color: #3a7bfa;" target="_blank">涓嬭浇 PDF 鏂囦欢</a></p>
+      </object>
+    </div>
+    <div v-if="isDoc">
+      <p v-if="!isDocShow">鏂囨。鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p>
+      <a :href="fileUrl" v-if="!isDocShow" target="_blank">涓嬭浇鏂囦欢</a>
+      <vue-office-docx v-else :src="fileUrl" style="height: 100vh;" @rendered="renderedHandler" @error="errorHandler" />
+    </div>
+    <div v-if="isXls">
+      <p v-if="!isDocShow">鏂囨。鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p>
+      <a :href="fileUrl" v-if="!isDocShow" target="_blank">涓嬭浇鏂囦欢</a>
+      <vue-office-excel v-else :src="fileUrl" :options="options" style="height: 100vh;" @rendered="renderedHandler"
+        @error="errorHandler" />
+    </div>
+    <div v-if="isZipOrRar">
+      <p>鍘嬬缉鏂囦欢鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p>
+      <a :href="fileUrl" target="_blank">涓嬭浇鏂囦欢</a>
+    </div>
+    <div v-if="isCsv">
+      <p v-if="csvList.length == 0">CSV 鏂囦欢鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p>
+      <a :href="fileUrl" v-if="csvList.length == 0" target="_blank">涓嬭浇鏂囦欢</a>
+      <el-tabs type="border-card" v-if="csvList.length > 0" tab-position="bottom">
+        <el-tab-pane :label="item.sheetName" v-for="(item, index) in csvList" :key="index">
+          <el-table :data="item.tableData" height="75vh">
+            <el-table-column :label="m.label" :prop="m.prop" v-for="(m, i) in item.column" :key="i" min-width="120px"
+              show-overflow-tooltip>
+              <template slot-scope="scope" slot="header">
+                <div>
+                  <el-tooltip :content="m.label" placement="top">
+                    <div class="oneLine">
+                      <span>{{ m.label }}</span>
+                    </div>
+                  </el-tooltip>
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+    <div v-if="!isSupported">
+      <p>涓嶆敮鎸佺殑鏂囦欢鏍煎紡</p>
+    </div>
+  </div>
+</template>
+
+<script>
+import VueOfficeDocx from '@vue-office/docx'
+//寮曞叆鐩稿叧鏍峰紡
+import '@vue-office/docx/lib/index.css'
+import VueOfficeExcel from '@vue-office/excel'
+//寮曞叆鐩稿叧鏍峰紡
+import '@vue-office/excel/lib/index.css'
+export default {
+  components: {
+    VueOfficeDocx,
+    VueOfficeExcel,
+  },
+  props: {
+    fileUrl: {
+      type: String,
+      required: true
+    },
+    currentFile: {
+      type: Object,
+      required: true
+    },
+  },
+  data() {
+    return {
+      isDocShow: true,
+      options: {
+        xls: false,       //棰勮xlsx鏂囦欢璁句负false锛涢瑙坸ls鏂囦欢璁句负true
+        minColLength: 0,  // excel鏈�灏戞覆鏌撳灏戝垪锛屽鏋滄兂瀹炵幇xlsx鏂囦欢鍐呭鏈夊嚑鍒楋紝灏辨覆鏌撳嚑鍒楋紝鍙互灏嗘鍊艰缃负0.
+        minRowLength: 0,  // excel鏈�灏戞覆鏌撳灏戣锛屽鏋滄兂瀹炵幇鏍规嵁xlsx瀹為檯鍑芥暟娓叉煋锛屽彲浠ュ皢姝ゅ�艰缃负0.
+        widthOffset: 10,  //濡傛灉娓叉煋鍑烘潵鐨勭粨鏋滄劅瑙夊崟鍏冩牸瀹藉害涓嶅锛屽彲浠ュ湪榛樿娓叉煋鐨勫垪琛ㄥ搴︿笂鍐嶅姞 Npx瀹�
+        heightOffset: 10, //鍦ㄩ粯璁ゆ覆鏌撶殑鍒楄〃楂樺害涓婂啀鍔� Npx楂�
+        beforeTransformData: (workbookData) => { return workbookData }, //搴曞眰閫氳繃exceljs鑾峰彇excel鏂囦欢鍐呭锛岄�氳繃璇ラ挬瀛愬嚱鏁帮紝鍙互瀵硅幏鍙栫殑excel鏂囦欢鍐呭杩涜淇敼锛屾瘮濡傛煇涓崟鍏冩牸鐨勬暟鎹樉绀轰笉姝g‘锛屽彲浠ュ湪姝よ嚜琛屼慨鏀规瘡涓崟鍏冩牸鐨剉alue鍊笺��
+        transformData: (workbookData) => { return workbookData }, //灏嗚幏鍙栧埌鐨別xcel鏁版嵁杩涜澶勭悊涔嬪悗涓旀覆鏌撳埌椤甸潰涔嬪墠锛屽彲閫氳繃transformData瀵瑰嵆灏嗘覆鏌撶殑鏁版嵁鍙婃牱寮忚繘琛屼慨鏀癸紝姝ゆ椂姣忎釜鍗曞厓鏍肩殑text鍊煎氨鏄嵆灏嗘覆鏌撳埌椤甸潰涓婄殑鍐呭
+      },
+      csvList: [],//csv鏂囦欢鏁版嵁
+      imgUrl: ''
+    }
+  },
+  computed: {
+    isImage() {
+      let state = /\.(jpg|jpeg|png|gif)$/i.test(this.fileUrl)
+      this.imgUrl = this.fileUrl
+      if (state) {
+        this.imgUrl = this.fileUrl.replaceAll('word', 'img')
+      }
+      console.log(11111, this.imgUrl)
+      return state;
+    },
+    isPdf() {
+      return /\.pdf$/i.test(this.fileUrl);
+    },
+    isDoc() {
+      return /\.(doc|docx)$/i.test(this.fileUrl);
+    },
+    isXls() {
+      let state = /\.(xls|xlsx)$/i.test(this.fileUrl)
+      if (state) {
+        if (/\.(xlsx)$/i.test(this.fileUrl)) {
+          this.options.xls = false
+        } else {
+          this.options.xls = true
+        }
+      }
+      return state;
+    },
+    isZipOrRar() {
+      return /\.(zip|rar)$/i.test(this.fileUrl);
+    },
+    isCsv() {
+      let state = /\.csv$/i.test(this.fileUrl)
+      if (state) {
+        this.loadCSVData();
+        // this.main()
+      }
+      return state;
+    },
+    isSupported() {
+      return this.isImage || this.isPdf || this.isDoc || this.isZipOrRar || this.isCsv || this.isXls;
+    }
+  },
+  methods: {
+    renderedHandler() {
+      console.log("娓叉煋瀹屾垚")
+      this.isDocShow = true
+      this.resetStyle()
+    },
+    errorHandler() {
+      console.log("娓叉煋澶辫触")
+      this.isDocShow = false
+    },
+    async loadCSVData() {
+      this.$axios.post(this.$api.insOrderPlan.preview, {
+        id: this.currentFile.id,
+      }).then(res => {
+        let arr = res.data
+        arr = arr.map(m => {
+          let obj = {
+            sheetName: m.sheetName,
+            tableData: [],
+            column: []
+          }
+          obj.tableData = this.formatCSVToTable(m.content.replaceAll('null', ' '))
+          // .replaceAll('MIN','=MIN').replaceAll('MAX','=MAX').replaceAll('AVERAGE','=AVERAGE')
+          for (let item in obj.tableData[0]) {
+            obj.column.push({
+              label: item,
+              prop: item,
+            })
+          }
+          return obj
+        })
+        this.csvList = arr
+      }).catch(err => {
+        console.log(err)
+      })
+    },
+    formatCSVToTable(str) {
+      const result = [];
+      const jsonObj = str.split("\n");
+      let arrHeader = [];
+      for (const i in jsonObj) {
+        if (typeof jsonObj[i] === 'string' && jsonObj[i].length > 0) {
+          const row = `${jsonObj[i]}`;
+          if (row.trim().length > 0) {
+            const kv = jsonObj[i].split(',');
+            if (i == 0) {
+              // 鑾峰彇column琛ㄥご
+              arrHeader = kv;
+            } else {
+              const obj = {};
+              for (let index = 0; index < arrHeader.length; index++) {
+                // 缁勮琛ㄦ牸鏁版嵁
+                const name = String(arrHeader[index]);
+                if (!arrHeader[index]) continue
+                if (!obj[name]) {
+                  try {
+                    if (kv[index]) {
+                      obj[name] = String(kv[index]);
+                    } else {
+                      obj[name] = '';
+                    }
+                  } catch (err) {
+                    obj[name] = '';
+                  }
+                }
+              }
+              result.push(obj);
+            }
+          }
+        }
+      }
+      return result
+    },
+    resetStyle() {
+      const elements = document.querySelectorAll('[style*="pt"]');
+      for (const element of elements) {
+        const style = element.getAttribute('style');
+        if (!!style) {
+          element.setAttribute('style', style.replace(/pt/g, 'px'));
+        }
+      }
+    },
+  }
+}
+</script>
+
+<style scoped>
+img {
+  max-width: 100%;
+}
+
+.oneLine {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+</style>

--
Gitblit v1.9.3