中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

純靜態(tài)網(wǎng)站制作seo整站優(yōu)化報價

純靜態(tài)網(wǎng)站制作,seo整站優(yōu)化報價,做學(xué)術(shù)論文的網(wǎng)站,公司想做個自己的網(wǎng)站怎么做的實際開發(fā)中,常見pdf|word|excel等文件的預(yù)覽和下載 背景相關(guān)類型數(shù)據(jù)之間的轉(zhuǎn)換1、File轉(zhuǎn)Blob2、File轉(zhuǎn)ArrayBuffer3、Blob轉(zhuǎn)ArrayBuffer4、Blob轉(zhuǎn)File5、ArrayBuffer轉(zhuǎn)Blob6、ArrayBuffer轉(zhuǎn)File 根據(jù)Blob/File類型生成可預(yù)覽的Base64地址基于Blob類型的各種文件的下載各種類型…

實際開發(fā)中,常見pdf|word|excel等文件的預(yù)覽和下載

    • 背景
    • 相關(guān)類型數(shù)據(jù)之間的轉(zhuǎn)換
      • 1、File轉(zhuǎn)Blob
      • 2、File轉(zhuǎn)ArrayBuffer
      • 3、Blob轉(zhuǎn)ArrayBuffer
      • 4、Blob轉(zhuǎn)File
      • 5、ArrayBuffer轉(zhuǎn)Blob
      • 6、ArrayBuffer轉(zhuǎn)File
    • 根據(jù)Blob/File類型生成可預(yù)覽的Base64地址
    • 基于Blob類型的各種文件的下載
    • 各種類型文件的預(yù)覽及其效果
      • 1、當(dāng)前使用的node版本
      • 2、 業(yè)務(wù)場景
      • 3、圖片類型預(yù)覽
        • 3.1、安裝依賴
        • 3.2、ImagePreview.vue
        • 3.3、效果
      • 4、Excel文件的預(yù)覽
        • 4.1、依賴安裝
        • 4.2、ExcelPreview.vue
        • 4.3、預(yù)覽效果
      • 5、word文件的預(yù)覽
        • 5.1、依賴安裝
        • 5.2、WordPreview.vue
        • 5.3、預(yù)覽效果
      • 6、pdf文件的預(yù)覽
        • 6.1、依賴安裝
        • 6.2、PdfPreview.vue
        • 6.3、預(yù)覽效果
      • 7、json/xml文件的預(yù)覽
        • 7.1、依賴安裝
        • 7.2、全局引入
        • 7.3、JsonViewer組件的使用
        • 7.4、預(yù)覽效果
      • 8、bim文件的預(yù)覽
        • 8.1、依賴安裝
        • 8.2、GeoBimPreview.vue
        • 8.3、預(yù)覽效果

背景

實際開發(fā)中,大部分文件的預(yù)覽會以流的方式傳輸,前端通過Element等UI庫提供的上傳組件傳給后端File類型數(shù)據(jù), 后端返回給前端Blob/ArrayBuffer類型數(shù)據(jù) , 前端最終借助各種第三方工具或者自定義tool方法, 實現(xiàn)各種類型文件的下載或者預(yù)覽. 少部分的會以文件地址的方式進(jìn)行傳輸, 那么我們直接訪問那個文件url即可.

相關(guān)類型數(shù)據(jù)之間的轉(zhuǎn)換

1、File轉(zhuǎn)Blob

export function fileToBlob(file: File) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => {const arrayBuffer: any = reader.result;const blob = new Blob([arrayBuffer], { type: file.type });resolve(blob);};reader.onerror = reject;reader.readAsArrayBuffer(file);});
}

在這里插入圖片描述

2、File轉(zhuǎn)ArrayBuffer

export function fileToArrayBuffer(file: File) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => {const arrayBuffer: any = reader.result;resolve(arrayBuffer);};reader.onerror = reject;reader.readAsArrayBuffer(file);});
}

3、Blob轉(zhuǎn)ArrayBuffer

export function blobToArrayBuffer(blob) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => resolve(reader.result);reader.onerror = reject;reader.readAsArrayBuffer(blob);});
}

4、Blob轉(zhuǎn)File

export function blobToFile(blob, fileName, fileType) {return new File([blob], fileName, { type: fileType })
}

5、ArrayBuffer轉(zhuǎn)Blob

export function arrayBufferToBlob(arrayBuffer, blobType = 'application/octet-stream') {const blob = new Blob([arrayBuffer], { type: blobType  });return blob;
}

6、ArrayBuffer轉(zhuǎn)File

export function arrayBufferToFile(arrayBuffer, fileName, fileType = 'text/plain') {const file= new File([arrayBuffer], fileName, { type: fileType  });return file;
}

根據(jù)Blob/File類型生成可預(yù)覽的Base64地址

有些第三方預(yù)覽工具不識別Blob/File, 如viewerjsv-viewer 預(yù)覽圖片的時候,是需要圖片對應(yīng)的src的,而不是Blob/File

export function createUrlByBlobOrFile(data: any) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => {resolve(reader.result);};reader.onerror = reject;reader.readAsDataURL(data);});
}

基于Blob類型的各種文件的下載

下載的文件響應(yīng)類型可打印FIle/Blob對象查看,可執(zhí)行:downloadFileUtil(fileBlob, fileBlob.type, fileBlob.fileName)

export function downloadFileUtil(data: Blob, responseType: string, fileName: any = new Date().valueOf()) {const blob = new Blob([data], { type: responseType });// 創(chuàng)建一個<a></a>標(biāo)簽let a: HTMLAnchorElement | null = document.createElement('a');const blobUrl = window.URL.createObjectURL(blob);a.href = blobUrl;a.download = fileName;a.style.display = 'none';document.body.appendChild(a);a.click();a.remove();// 釋放createObjectURL創(chuàng)建的資源window.URL.revokeObjectURL(blobUrl);
}

各種類型文件的預(yù)覽及其效果

個別預(yù)覽的第三方插件庫,需要使用特定的某些版本,當(dāng)前指定的版本庫都是可用的。

1、當(dāng)前使用的node版本

在這里插入圖片描述

2、 業(yè)務(wù)場景

  • 用戶通過上傳組件上傳附件

用戶從本地上傳的附件拿到的類型是File, 保存之后, 拿到的就是文件列表項對應(yīng)的Blob類型。
在這里插入圖片描述

3、圖片類型預(yù)覽

圖片類型預(yù)覽使用的是v-viewerviewerjs, 可支持的預(yù)覽圖片類型有:jpg, jpeg, png, gif

3.1、安裝依賴
yarn add v-viewer@^3.0.21 viewerjs@^1.11.7
3.2、ImagePreview.vue

v-viewerviewerjs 可以通過指令、組件和api三種方式實現(xiàn)預(yù)覽。 實際開發(fā)中,基本上都是使用的是Blob類型,Blob類型轉(zhuǎn)換為Base64地址后, 是不能通過import { api as viewerApi } from 'v-viewer';的方式預(yù)覽的,盡管api的方式很簡單,但它貌似只是支持本地文件URL/服務(wù)器文件URL。

通過使用viewer組件,借助img標(biāo)簽可以識別Base64圖片路徑,從而通過點擊img列表,實現(xiàn)圖片預(yù)覽

<template><div class="image-preview"><viewer :images="props.images" class="v-viewer"><imgv-for="(imgItem, index) in props.images":key="index"class="view-img-item":src="imgItem.url":alt="imgItem.name":title="imgItem.name"/></viewer><div class="auto-close-preview-com"><Close class="close-icon" @click="closeImgPreviewFn" /></div></div>
</template><script lang="ts" setup>
import 'viewerjs/dist/viewer.css';
import { component as Viewer } from 'v-viewer';
import { onMounted } from 'vue';
import { ElMessage } from 'element-plus';const props = defineProps({images: {type: Array as any,  // images存儲的是Blob轉(zhuǎn)成Base64的數(shù)組,類型轉(zhuǎn)換上文createUrlByBlobOrFile可實現(xiàn)default: () => [],},
});
const emits = defineEmits(['closeImgPreview']);function closeImgPreviewFn() {emits('closeImgPreview');
}
onMounted(() => {ElMessage.info('點擊圖片列表可預(yù)覽~');
});
</script><style lang="css" scoped>
.image-preview {position: fixed;left: 0;top: 0;right: 0;bottom: 0;z-index: 9998;background-color: rgb(0 0 0 / 70%);.v-viewer {width: 100%;height: 100%;.view-img-item {width: 250px;height: 250px;margin-right: 20px;}}.auto-close-preview-com {position: absolute;-webkit-app-region: no-drag;background-color: rgb(0 0 0 / 50%);border-radius: 50%;cursor: pointer;height: 80px;overflow: hidden;right: -40px;top: -40px;transition: background-color 0.15s;width: 80px;color: #ffffff;.close-icon {bottom: 15px;left: 15px;position: absolute;background-position: -260px 0;font-size: 0;height: 20px;line-height: 0;width: 20px;}}
}
</style>
3.3、效果

在這里插入圖片描述

4、Excel文件的預(yù)覽

Excel文件預(yù)覽使用的是xlsx 插件庫, 可支持類型有:xls, xlsx

4.1、依賴安裝
yarn add xlsx@^0.18.5
4.2、ExcelPreview.vue
<template><div class="xlsx-preview-box"></div>
</template><script lang="ts" setup>
import { onMounted } from 'vue';
// XLSX: 無法預(yù)覽docx文件, 預(yù)覽pdf也會亂碼  只能預(yù)覽xlsx文件
import * as XLSX from 'xlsx';const props = defineProps({fileBlob: {type: Blob,default: () => null,},
});onMounted(() => {if (props.fileBlob) {const reader = new FileReader();// 通過readAsArrayBuffer將blob轉(zhuǎn)換為ArrayBufferreader.readAsArrayBuffer(props.fileBlob);reader.onload = (event: any) => {// 讀取ArrayBuffer數(shù)據(jù)變成Uint8Arrayconst data = new Uint8Array(event.target.result);// 這里的data里面的類型和后面的type類型要對應(yīng)const workbook = XLSX.read(data, { type: 'array' });const sheetNames = workbook.SheetNames; // 工作表名稱const worksheet = workbook.Sheets[sheetNames[0]];const html = XLSX.utils.sheet_to_html(worksheet);document.getElementsByClassName('xlsx-preview-box')[0].innerHTML = html;};}
});
</script><style lang="css">
.xlsx-preview-box {width: 100%;height: 100%;overflow: auto;table {width: 100%;border-spacing: 0;tr {height: 40px;font-size: 14px;color: #666666;line-height: 14px;font-weight: 400;}tr:first-child {background-color: #ececec !important;height: 60px;font-size: 16px;color: #666666;font-weight: 700;}td {min-width: 80px;text-align: center;border: 1px solid #cccccc;}tr:nth-child(2n) {background-color: #fafafa;}tr:nth-child(2n + 1) {background-color: #ffffff;}}
}
</style>
4.3、預(yù)覽效果

在這里插入圖片描述

5、word文件的預(yù)覽

word文件預(yù)覽使用的是docx-preview 插件庫, 可支持類型有:doc, docx。

5.1、依賴安裝
yarn add docx-preview@0.3.0

docx-preview 需要是0.3.0版本,最新的0.3.3版本會報docx-preview類型錯誤。且最新的版本解析的blob文件類型和0.3.0版本不一致,最新版本還會預(yù)覽失敗:報(Can’t find end of central directory : is this a zip file ? If it is, see)。

5.2、WordPreview.vue
<template><div ref="wordPreviewRef" class="word-preview"></div>
</template><script lang="ts" setup>
import { ref, nextTick } from 'vue';
// docx-preview 需要是0.3.0版本,最新的0.3.3版本會報docx-preview類型錯誤
// 且最新的版本解析的blob類型和0.3.0版本不一致
// 最新版本還會預(yù)覽失敗:報(Can't find end of central directory : is this a zip file ? If it is, see)
import { renderAsync } from 'docx-preview';const props = defineProps<{wordBlob: any;
}>();const wordPreviewRef = ref({});nextTick(() => {renderAsync(props.wordBlob, // blob 的type: application/vnd.openxmlformats-officedocument.wordprocessingml.documentwordPreviewRef.value as HTMLElement, // HTMLElement 渲染文檔內(nèi)容的元素,);
});
</script><style lang="scss" scoped>
.word-preview {width: 100%;height: 100%;overflow: auto;
}
</style>
5.3、預(yù)覽效果

在這里插入圖片描述

6、pdf文件的預(yù)覽

pdf文件預(yù)覽使用的是pdfjs-dist 插件庫, 可支持類型有:pdf

6.1、依賴安裝
yarn add pdfjs-dist@2.16.105

pdfjs-dist 底層是pdfjs。不建議使用打包后的mjs類型的版本包。因為不支持線上環(huán)境對GlobalWorkerOptions.workerSrc的支持。具體的是:本地可以引入node_module路徑,但是正式環(huán)境沒這個路徑;如果把對應(yīng)的pdf.worker.min.mjs放到assets下,會報錯:Failed to resolve module specifier '@/assets/pdfjs/pdf.worker.min.mjs; 如果放到public下,會報錯Failed to load module script, public目錄文件不會被編譯,瀏覽器無法識別mjs文件

6.2、PdfPreview.vue
<template><div class="pdf-preview"><!-- block: 避免一個視圖顯示多個canvas頁 --><canvasv-for="pageIndex in pdfPages":id="`pdf-canvas-` + pageIndex"ref="pdfPreviewRef":key="pageIndex"style="display: block"></canvas></div>
</template><script lang="ts" setup>
import { ref, onMounted, nextTick, reactive } from 'vue';// import 'pdfjs-dist/web/pdf_viewer.css';
// 4.5.136版本
// import * as pdfjsLib from 'pdfjs-dist'; // /legacy/build/pdf.js
// import * as pdfjsViewer from 'pdfjs-dist/web/pdf_viewer.js';
import 'pdfjs-dist/web/pdf_viewer.css';
import * as pdfjsLib from 'pdfjs-dist';
import { blobToArrayBuffer } from '@/utils/tools';const props = defineProps<{pdfBlob: any;
}>();const pdfPreviewRef = ref({});
// pdf頁數(shù)
const pdfPages = ref(0);
// pdf縮放比例
const pdfScale = ref(2.5); // 可以控制canvas的寬高
// pdf文檔流,
// 這個不能使用ref,使用ref會報錯: Cannot read from private field
let pdfDoc = reactive<any>({});const renderPdf = (num) => {pdfDoc.getPage(num).then((page) => {const canvasId = `pdf-canvas-${num}`;const canvas: any = document.getElementById(canvasId);const ctx = canvas?.getContext('2d');const dpr = window.devicePixelRatio || 1;const bsr =ctx.webkitBackingStorePixelRatio ||ctx.mozBackingStorePixelRatio ||ctx.msBackingStorePixelRatio ||ctx.oBackingStorePixelRatio ||ctx.backingStorePixelRatio ||1;const ratio = dpr / bsr;const viewport = page.getViewport({ scale: pdfScale.value });canvas.width = viewport.width * ratio;canvas.height = viewport.height * ratio;canvas.style.width = `${viewport.width}px`;canvas.style.height = `${viewport.height}px`;ctx.setTransform(ratio, 0, 0, ratio, 0, 0);const renderContext = {canvasContext: ctx,viewport: viewport,};page.render(renderContext);if (num < pdfPages.value) {renderPdf(num + 1);}});
};// 獲取pdf文檔流與pdf文件的頁數(shù)
const loadFile = async () => {//  string | URL | TypedArray | ArrayBuffer | DocumentInitParametersconst pdfArrayBuffer: any = await blobToArrayBuffer(props.pdfBlob);const loadingTask = pdfjsLib.getDocument(pdfArrayBuffer);loadingTask.promise.then((pdf) => {pdfDoc = pdf; // 獲取pdf文檔流pdfPages.value = pdf.numPages; // 獲取pdf文件的頁數(shù)nextTick(() => {renderPdf(1);});});
};onMounted(async () => {// 正式環(huán)境找不到node_modules// pdfjsLib.GlobalWorkerOptions.workerSrc =//   '../../../node_modules/pdfjs-dist/build/pdf.worker.min.mjs';// 放在assets下: Failed to resolve module specifier '@/assets/pdfjs/pdf.worker.min.mjs// pdfjsLib.GlobalWorkerOptions.workerSrc = '@/assets/pdfjs/pdf.worker.min.mjs';// const baseurl = window.location.origin + window.location.pathname; // 本地路徑// ${baseurl}pdfjs/pdf.worker.min.mjs 靜態(tài)服務(wù)訪問的返回的是流// pdfjsLib.GlobalWorkerOptions.workerSrc = `${baseurl}pdfjs/pdf.worker.min.mjs`; // Failed to load module script// public/pdfjs/pdf.worker.js: 將'../../../node_modules/pdfjs-dist/build/pdf.worker.js';復(fù)制到public目錄下pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs/pdf.worker.js';  // “pdfjs/”不能寫成“/pdfjs/”, 前者是相對路徑, 后者是絕對路徑(相對線上環(huán)境服務(wù)器)loadFile();
});
</script>
<style lang="scss" scoped>
.pdf-preview {width: 100%;height: 100%;overflow: auto;
}
</style>
6.3、預(yù)覽效果

在這里插入圖片描述

7、json/xml文件的預(yù)覽

vue-json-viewer支持jsonxml文件的預(yù)覽

7.1、依賴安裝
yarn add vue-json-viewer@^3.0.4
7.2、全局引入

在這里插入圖片描述

7.3、JsonViewer組件的使用

fileData存儲的是后端接口返回的json字符串

<json-viewer v-else-if="preState.fileType === 'Json'" :value="preState.fileData" />
7.4、預(yù)覽效果

在這里插入圖片描述
在這里插入圖片描述

8、bim文件的預(yù)覽

geobim文件的預(yù)覽使用的是@xbim/viewer插件庫,當(dāng)前使用的方式支持BlobUrl兩種方式

8.1、依賴安裝
yarn add @xbim/viewer@^2.1.0-pre202305041434
8.2、GeoBimPreview.vue

該組件接收的是url, 但是loadGeoBim處理兼容了Blob

<template><canvas id="bim-canvas" style="width: 100%; height: 100%"></canvas>
</template><script lang="ts" setup>
import { watch, nextTick } from 'vue';
import { Grid, NavigationCube, Viewer, ViewType } from '@xbim/viewer';const props = defineProps({dwgUrl: {type: String,default: () => '',},
});
let viewer;
const setViewerOptions = () => {viewer.background = [26, 51, 76, 255];viewer.highlightingColour = [0, 0, 225, 200];viewer.brightness = -0.5;viewer.hoverPickColour = [0, 0, 225, 200];
};
const setViewerPlugin = () => {const cube = new NavigationCube();cube.ratio = 0.05;// eslint-disable-next-line no-multi-assigncube.passiveAlpha = cube.activeAlpha = 0.85;viewer.addPlugin(new Grid());viewer.addPlugin(cube);
};
const token = localStorage.getItem('TOKEN') as string;
const headers = {Authorization: `Bearer ${JSON.parse(token).access_token}`,
};
const loadGeoBim = (dwgUrl) => {const check = Viewer.check();if (check.noErrors) {nextTick(() => {viewer = new Viewer('bim-canvas');setViewerOptions();setViewerPlugin();viewer.on('loaded', function () {viewer.show(ViewType.DEFAULT, undefined, undefined, false);viewer.start();});// 前置管理、任務(wù)管理、數(shù)據(jù)管理里訪問的數(shù)據(jù)是四庫的后端接口返回的文件流,服務(wù)管理里訪問的是可視化系統(tǒng)后臺接口返回的文件地址// node_modules\.vite\deps\@xbim_viewer.js  修復(fù)bim的左右鍵fetch(dwgUrl, { headers }).then((responce) => responce.arrayBuffer()).then((arrayBuffer) => {const blob = new Blob([arrayBuffer], { type: 'application/octet-stream' });viewer.load(blob);}).catch((err) => {viewer.load(dwgUrl);});});}
};
watch(() => props.dwgUrl,(dwgUrl) => {loadGeoBim(dwgUrl);},{immediate: true,deep: true,},
);
</script>
8.3、預(yù)覽效果

在這里插入圖片描述

http://www.risenshineclean.com/news/11695.html

相關(guān)文章:

  • 一個網(wǎng)站的后臺怎么做太原網(wǎng)站建設(shè)
  • 百度怎樣做網(wǎng)站并宣傳網(wǎng)站長春網(wǎng)站建設(shè)公司哪家好
  • 鄭州婦科醫(yī)院正規(guī)有哪些廣州seo營銷培訓(xùn)
  • 煤礦黨風(fēng)廉政建設(shè)網(wǎng)站如何注冊域名
  • 淘客做的領(lǐng)券網(wǎng)站黑帽seo優(yōu)化推廣
  • 為什么用wp做網(wǎng)站沈陽網(wǎng)站制作優(yōu)化推廣
  • 對視頻播放網(wǎng)站做性能測試查排名的軟件有哪些
  • c2c電子商務(wù)網(wǎng)站策劃深圳市龍華區(qū)
  • 做的好看的網(wǎng)站免費網(wǎng)站優(yōu)化排名
  • 做網(wǎng)站便宜新聞源
  • wordpress隱藏服務(wù)器ip網(wǎng)站seo優(yōu)化分析
  • 廣州市做民宿什么網(wǎng)站比較好seo搜論壇
  • 什么網(wǎng)站可以免費做找客戶谷歌seo快速排名優(yōu)化方法
  • vs做網(wǎng)站教程長春網(wǎng)站關(guān)鍵詞排名
  • 東莞模板建站軟件seo專員
  • 視頻網(wǎng)站如何建設(shè)專業(yè)代寫軟文
  • 武漢招聘一般用什么網(wǎng)站沙洋縣seo優(yōu)化排名價格
  • 對酒店網(wǎng)站建設(shè)的意見互聯(lián)網(wǎng)廣告行業(yè)
  • 喀什做網(wǎng)站seo快速排名源碼
  • wordpress 菜單 標(biāo)簽科學(xué)新概念seo外鏈平臺
  • 照片做視頻ppt模板下載網(wǎng)站知識營銷成功案例介紹
  • 淡水做網(wǎng)站網(wǎng)頁設(shè)計主題參考
  • word做招聘網(wǎng)站長尾詞挖掘
  • 電影日記網(wǎng)站怎么做界首網(wǎng)站優(yōu)化公司
  • 有免費的網(wǎng)址嗎南寧seo專員
  • 做網(wǎng)站造假域名推薦
  • 做論壇網(wǎng)站前段用什么框架好點網(wǎng)絡(luò)廣告的概念
  • 公司網(wǎng)站建設(shè)會計上怎么處理百度產(chǎn)品大全入口
  • 華為公司網(wǎng)站建設(shè)方案網(wǎng)站模板圖片
  • 成立做網(wǎng)站的公司網(wǎng)絡(luò)推廣一個月工資多少