實際開發中,常見pdf|word|excel等文件的預覽和下載

實際開發中,常見pdf|word|excel等文件的預覽和下載

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

背景

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

相關類型數據之間的轉換

1、File轉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轉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轉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轉File

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

5、ArrayBuffer轉Blob

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

6、ArrayBuffer轉File

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

根據Blob/File類型生成可預覽的Base64地址

有些第三方預覽工具不識別Blob/File, 如viewerjsv-viewer 預覽圖片的時候,是需要圖片對應的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類型的各種文件的下載

下載的文件響應類型可打印FIle/Blob對象查看,可執行: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 });// 創建一個<a></a>標簽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創建的資源window.URL.revokeObjectURL(blobUrl);
}

各種類型文件的預覽及其效果

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

1、當前使用的node版本

在這里插入圖片描述

2、 業務場景

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

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

3、圖片類型預覽

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

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

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

通過使用viewer組件,借助img標簽可以識別Base64圖片路徑,從而通過點擊img列表,實現圖片預覽

<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轉成Base64的數組,類型轉換上文createUrlByBlobOrFile可實現default: () => [],},
});
const emits = defineEmits(['closeImgPreview']);function closeImgPreviewFn() {emits('closeImgPreview');
}
onMounted(() => {ElMessage.info('點擊圖片列表可預覽~');
});
</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文件的預覽

Excel文件預覽使用的是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: 無法預覽docx文件, 預覽pdf也會亂碼  只能預覽xlsx文件
import * as XLSX from 'xlsx';const props = defineProps({fileBlob: {type: Blob,default: () => null,},
});onMounted(() => {if (props.fileBlob) {const reader = new FileReader();// 通過readAsArrayBuffer將blob轉換為ArrayBufferreader.readAsArrayBuffer(props.fileBlob);reader.onload = (event: any) => {// 讀取ArrayBuffer數據變成Uint8Arrayconst data = new Uint8Array(event.target.result);// 這里的data里面的類型和后面的type類型要對應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、預覽效果

在這里插入圖片描述

5、word文件的預覽

word文件預覽使用的是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版本不一致,最新版本還會預覽失敗:報(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版本不一致
// 最新版本還會預覽失敗:報(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 渲染文檔內容的元素,);
});
</script><style lang="scss" scoped>
.word-preview {width: 100%;height: 100%;overflow: auto;
}
</style>
5.3、預覽效果

在這里插入圖片描述

6、pdf文件的預覽

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

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

pdfjs-dist 底層是pdfjs。不建議使用打包后的mjs類型的版本包。因為不支持線上環境對GlobalWorkerOptions.workerSrc的支持。具體的是:本地可以引入node_module路徑,但是正式環境沒這個路徑;如果把對應的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頁數
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文件的頁數
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文件的頁數nextTick(() => {renderPdf(1);});});
};onMounted(async () => {// 正式環境找不到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 靜態服務訪問的返回的是流// 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';復制到public目錄下pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs/pdf.worker.js';  // “pdfjs/”不能寫成“/pdfjs/”, 前者是相對路徑, 后者是絕對路徑(相對線上環境服務器)loadFile();
});
</script>
<style lang="scss" scoped>
.pdf-preview {width: 100%;height: 100%;overflow: auto;
}
</style>
6.3、預覽效果

在這里插入圖片描述

7、json/xml文件的預覽

vue-json-viewer支持jsonxml文件的預覽

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、預覽效果

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

8、bim文件的預覽

geobim文件的預覽使用的是@xbim/viewer插件庫,當前使用的方式支持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();});// 前置管理、任務管理、數據管理里訪問的數據是四庫的后端接口返回的文件流,服務管理里訪問的是可視化系統后臺接口返回的文件地址// node_modules\.vite\deps\@xbim_viewer.js  修復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、預覽效果

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/65326.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/65326.shtml
英文地址,請注明出處:http://en.pswp.cn/web/65326.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

微信小程序中的 storage(本地存儲)和內存是兩個完全不同的存儲區域

這是一個非常關鍵且容易混淆的概念 既然 this.globalData.appId appId 是將 appId 存儲在內存中&#xff0c;為什么微信小程序中的 wx.getStorage 和 wx.setStorage&#xff08;本地存儲&#xff09;中沒有 appId&#xff0c;并且您提出了一個非常重要的疑問&#xff1a;stor…

【C++數據結構——查找】二叉排序樹(頭歌實踐教學平臺習題)【合集】

目錄&#x1f60b; 任務描述 相關知識 1. 二叉排序樹的基本概念 2. 二叉排序樹節點結構體定義 3. 創建二叉排序樹 4. 判斷是否為二叉排序樹 5. 遞歸查找關鍵字為 6 的結點并輸出查找路徑 6. 刪除二叉排序樹中的節點 測試說明 通關代碼 測試結果 任務描述 本關任務&a…

計算機網絡(第8版)第3章課后習題--透明傳輸

【3-11】 試分別討論以下各種情況在什么條件下是透明傳輸&#xff0c;在什么條件下不是透明傳 輸。(提示&#xff1a;請弄清什么是“透明傳輸”,然后考慮能否滿足其條件。) (1)普通的電話通信。 (2)互聯網提供的電子郵件服務。 解 答 &#xff1a; 透明傳輸是指在數據傳輸…

Linux(17)——使用 DNF 安裝和更新軟件包

目錄 一、使用 DNF 管理軟件包&#xff1a; 1、 DNF 查找軟件&#xff1a; 2、DNF 安裝軟件&#xff1a; 3、DNF 刪除軟件&#xff1a; 二、使用 DNF 管理軟件包組&#xff1a; 1、DNF 顯示組信息&#xff1a; 2、DNF 安裝組&#xff1a; 三、使用 DNF 查看事務歷史記錄…

基于32單片機的智能語音家居

一、主要功能介紹 以STM32F103C8T6單片機為控制核心&#xff0c;設計一款智能遠程家電控制系統&#xff0c;該系統能實現如下功能&#xff1a; 1、可通過語音命令控制照明燈、空調、加熱器、窗戶及窗簾的開關&#xff1b; 2、可通過手機顯示和控制照明燈、空調、窗戶及窗簾的開…

Qt 5.14.2 學習記錄 —— ? 新項目

文章目錄 1、創建2、查看代碼 ---- main.cpp3、查看代碼 ---- widgt.h4、查看代碼 ---- widgt.cpp和widget.ui5、查看代碼 ---- Empty.pro6、運行產生的中間文件 1、創建 左上角的文件&#xff0c;新建文件或項目。如果要寫一個GUI程序&#xff0c;應當選擇Application&#x…

linux wsl配置 redis遠程連接

? 1. 修改 Redis 配置文件 在 WSL 的 Redis 配置文件中&#xff0c;找到 redis.conf 或 /etc/redis/redis.conf 文件&#xff0c;編輯以下配置項&#xff1a; ?? 更新 bind 配置項 將 bind 127.0.0.1 ::1 修改為&#xff1a; bind 0.0.0.0這樣&#xff0c;Redis 將監聽所…

Transformer從零詳細解讀——DASOU講AI

1. 從全局角度概括Transformer transformer的任務是什么&#xff1f; 進一步細化 進一步細化&#xff0c;注意&#xff1a;每個encoder結構相同&#xff0c;參數不同&#xff1b;decoder同理 原論文中的圖如下&#xff1a; 2.Encoder 2.1 輸入部分 &#xff08;1&#xff09…

ARM發布Armv9.5架構:邁向更強性能與靈活性的新時代

2024年11月30日&#xff0c;ARM正式發布了其最新的Armv9.5架構&#xff0c;這是Arm技術發展的又一重要里程碑。從表中信息來看&#xff0c;Armv9.5架構的發布標志著該公司的架構系列在性能、靈活性和可擴展性方面取得了進一步突破。本次發布不僅是技術上的提升&#xff0c;更是…

【Python運維】使用Python與Docker進行高效的容器化應用管理

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 隨著容器化技術的廣泛應用,Docker已成為現代軟件開發與運維中不可或缺的工具。Docker容器提供了一種輕量級、可移植的方式來部署和管理應用…

分布式系統架構6:鏈路追蹤

這是小卷對分布式系統架構學習的第6篇文章&#xff0c;關于鏈路追蹤&#xff0c;之前寫過traceId的相關內容&#xff1a;https://juejin.cn/post/7135611432808218661&#xff0c;不過之前寫的太淺了&#xff0c;且不成系統&#xff0c;只是簡單的理解&#xff0c;今天來捋一下…

Ubuntu 20.04安裝gcc

一、安裝GCC 1.更新包列表 user596785154:~$ sudo apt update2.安裝gcc user596785154:~$ sudo apt install gcc3.驗證安裝 user596785154:~$ gcc --version二 編譯C文件 1.新建workspace文件夾 user596785154:~$ mkdir workspace2.進入workspace文件夾 user596785154:~…

問題:Flask應用中的用戶會話(Session)管理失效

我來分享一個常見的PythonWeb開發問題&#xff1a; 問題&#xff1a;Flask應用中的用戶會話(Session)管理失效 這是一個在Flask開發中經常遇到的問題。當用戶登錄后&#xff0c;有時會話會意外失效&#xff0c;導致用戶需要重復登錄。 解決方案&#xff1a; 1. 首先&#x…

ansible-性能優化

一. 簡述&#xff1a; 搞過運維自動化工具的人&#xff0c;肯定會發現很多運維伙伴們經常用saltstack和ansible做比較&#xff0c;單從執行效率上來說&#xff0c;ansible確實比不上saltstack(ansible使用的是ssh,salt使用的是zeromq消息隊列[暫沒深入了解])&#xff0c;但其實…

.net core 線程鎖,互斥鎖,自旋鎖,混合鎖

線程鎖、互斥鎖、自旋鎖和混合鎖是多線程編程中的重要概念&#xff0c;它們用于控制對共享資源的訪問&#xff0c;避免數據競爭和不一致性。每種鎖有其特定的適用場景和特點。我們來逐一解釋它們&#xff0c;并進行比較。 1. 線程鎖&#xff08;Thread Lock&#xff09; 線程…

【ArcGISPro/GeoScenePro】檢查并處理高程數據

數據 https://arcgis.com/sharing/rest/content/items/535efce0e3a04c8790ed7cc7ea96d02d/data 數字高程模型 (DEM) 是一種柵格,可顯示地面或地形的高程。 數字表面模型 (DSM) 是另一種高程柵格,可顯示表面的高度,例如建筑物或樹冠的頂部。 您需要準備 DEM 和 DSM 以供分析…

【C++面向對象——類與對象】Computer類(頭歌實踐教學平臺習題)【合集】

目錄&#x1f60b; 任務描述 相關知識 一、不同訪問屬性成員的訪問方式 1. public成員 2. private成員 3. protected成員 二、觀察構造函數和析構函數的執行過程 1. 構造函數 2. 析構函數 三、學習類的組合使用方法 1. 類的組合概念 2. 實現示例 實驗步驟 測試說明 …

xilinx的高速接口構成原理和連接結構及ibert工具的使用-以k7 GTX為例

一、相關簡介 Xilinx的高速接口稱之為transceivers(高速收發器&#xff09;&#xff0c;這部分的電路是專用電路&#xff0c;供電等都是獨立的&#xff0c;根據速率可以分為GTP/GTX/GTH/GTY/GTM等。 Xilinx的高速接口是QUAD為單位的&#xff0c;沒一個QUAD由一個時鐘COMMON資…

創建型模式4.原型模式

創建型模式 工廠方法模式&#xff08;Factory Method Pattern&#xff09;抽象工廠模式&#xff08;Abstract Factory Pattern&#xff09;建造者模式&#xff08;Builder Pattern&#xff09;原型模式&#xff08;Prototype Pattern&#xff09;單例模式&#xff08;Singleto…

python學opencv|讀取圖像(二十七)使用time()繪制彈球動畫

【1】引言 前序已經學習了pythonopencv畫線段、圓形、矩形、多邊形和文字的相關操作&#xff0c;具體文章鏈接包括且不限于&#xff1a; python學opencv|讀取圖像&#xff08;十八&#xff09;使用cv2.line創造線段_cv2. 畫線段-CSDN博客 python學opencv|讀取圖像&#xff0…