实际开发中,常见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.rhkb.cn/news/503113.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Vue3实战教程》19:Vue3组件 v-model

如果您有疑问&#xff0c;请观看视频教程《Vue3实战教程》 组件 v-model​ 基本用法​ v-model 可以在组件上使用以实现双向绑定。 从 Vue 3.4 开始&#xff0c;推荐的实现方式是使用 defineModel() 宏&#xff1a; vue <!-- Child.vue --> <script setup> co…

源代码编译安装X11及相关库、vim,配置vim(1)

一、目录结构 如下。 所有X11及相关库装到mybuild&#xff0c;源代码下载到src下&#xff0c;解压&#xff0c;进入&#xff0c;编译安装。编译时指定--prefix到相同的目录&#xff0c;即上图中mybuild。 ./configure --prefixpwd/../../mybuild [CFLAGS"-I/path/to/X11…

图漾相机基础操作

1.客户端概述 1.1 简介 PercipioViewer是图漾基于Percipio Camport SDK开发的一款看图软件&#xff0c;可实时预览相机输出的深度图、彩色图、IR红外图和点云图,并保存对应数据&#xff0c;还支持查看设备基础信息&#xff0c;在线修改gain、曝光等各种调节相机成像的参数功能…

vulnhub靶场-potato(至获取shell)

arp-scan -l 扫描IP 使用御剑端口扫描扫描端口&#xff0c;扫到了80和7120两个端口&#xff0c;其中7120为ssh端口 使用dirb http://192.168.171.134 扫描目录 发现info.php 访问为phpinfo界面 访问192.168.171.134为一个大土豆&#xff0c;没什么用 所以我们从ssh入手 盲…

谈一谈对事件循环的理解

事件循环⼜叫做消息循环&#xff0c;是浏览器渲染主线程的⼯作⽅式。特别是在JavaScript和Node.js等异步编程环境中&#xff0c;也是核心概念之一。它的主要作用是管理异步操作&#xff0c;确保代码的执行顺序和效率。 并且这个话题很有可能是一个面试题。我先把参考答案放下面…

kafka使用以及基于zookeeper集群搭建集群环境

一、环境介绍 zookeeper下载地址&#xff1a;https://zookeeper.apache.org/releases.html kafka下载地址&#xff1a;https://kafka.apache.org/downloads 192.168.142.129 apache-zookeeper-3.8.4-bin.tar.gz kafka_2.13-3.6.0.tgz 192.168.142.130 apache-zookee…

解决 IntelliJ IDEA 中 Tomcat 日志乱码问题的详细指南

目录 前言1. 分析问题原因2. 解决方案 2.1 修改 IntelliJ IDEA 的 JVM 选项2.2 配置 Tomcat 实例的 VM 选项 2.2.1 设置 Tomcat 的 VM 选项2.2.2 添加环境变量 3. 进一步优化 3.1 修改 Tomcat 的 logging.properties3.2 修改操作系统默认编码 3.2.1 Windows 系统3.2.2 Linux …

067B-基于R语言平台Biomod2模型的物种分布建模与数据可视化-高阶课程【2025】

课程培训包含&#xff1a;发票全套软件脚本学习数据视频文件导师答疑 本教程旨在通过系统的培训学习&#xff0c;学员可以掌握Biomod2模型最新版本的使用方法&#xff0c;最新版包含12个模型&#xff08;ANN, CTA, FDA, GAM, GBM, GLM, MARS, MAXENT, MAXNET, RF, SRE, XGBOOST…

【论文复现】改进麻雀搜索算法优化冷水机组的最优负载调配问题

目录 1.摘要2.麻雀搜索算法SSA原理3.改进策略4.结果展示5.参考文献6.代码获取 1.摘要 为了应对暖通空调&#xff08;HVAC&#xff09;系统由于不当负荷分配导致的高能源消耗问题&#xff0c;本文提出了一种改进麻雀搜索算法&#xff08;ISSA&#xff09;。ISSA算法旨在在满足负…

Java实现下载excel模板,并实现自定义下拉框

GetMapping("excel/download")ApiOperation(value "模板下载")public void getUserRecordTemplate(HttpServletResponse response, HttpServletRequest request) throws IOException {OutputStream outputStream response.getOutputStream();InputStream…

UCAS-算法设计与分析(专硕)-复习参考

算法设计与分析&#xff08;专硕&#xff09; 希望对后来者选课 or 复习提供参考 考试时间&#xff1a;2025年1月6日 18:10~21:00 15 个选择、10个填空、10个计算大题 三个小时&#xff0c;手没有停过&#xff0c;不停得在算&#xff0c;好在没有留空&#xff0c;但已知有些内…

什么样的人适合从事FPGA开发的工作?

FPGA开发不仅要求扎实的技术基础&#xff0c;还非常看重团队合作、自信、沟通技巧以及细致入微的工作态度。从业者需具备面对复杂项目的自信&#xff0c;优秀的沟通能力以确保团队协作顺畅&#xff0c;严谨细心以应对精密的硬件设计&#xff0c;以及强烈的责任心来驱动每一个开…

GitLab 创建项目、删除项目

1、创建项目 点击左上角图标&#xff0c;回到首页 点击 Create a project 点击 Create blank project 输入项目名称&#xff0c;点击Create Project 创建成功 2、删除项目 进入项目列表 点击对应项目&#xff0c;进入项目 进入Settings页面 拖到页面底部&#xff0c;展开Adva…

Visual studio code编写简单记事本exe笔记

安装扩展cmake tools c/c c/c Extension pack CMakeLists.txt cmake_minimum_required(VERSION 3.20) project(NotepadApp)set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON)# Windows specific settings if(WIN32)set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)s…

容器技术思想 Docker K8S

容器技术介绍 以Docker为代表的容器技术解决了程序部署运行方面的问题。在容器技术出现前&#xff0c;程序直接部署在物理服务器上&#xff0c;依赖管理复杂&#xff0c;包括各类运行依赖&#xff0c;且易变&#xff0c;多程序混合部署时还可能产生依赖冲突&#xff0c;给程序…

导出中心设计

业务背景 应用业务经常需要导出数据&#xff0c;但是并发的导出以及不合理的导出参数常常导致应用服务的内存溢出、其他依赖应用的崩溃、导出失败&#xff1b;因此才有导出中心的设计 设计思想 将导出应用所需的内存转移至导出中心&#xff0c;将导出的条数加以限制&#xf…

Unity 中计算射线和平面相交距离的原理

有此方法 能够计算射线和平面是否相交以及射线起点到平面交点的距离 代码分析 var dot Vector3.Dot(ray.direction, plane.normal);计算射线和平面法线的点积&#xff0c;如果大于等于0&#xff0c;则说明射线和平面没有相交&#xff0c;否则&#xff0c;说明射线和平面相交…

网络安全抓包

#知识点&#xff1a; 1、抓包技术应用意义 //有些应用或者目标是看不到的&#xff0c;这时候就要进行抓包 2、抓包技术应用对象 //app,小程序 3、抓包技术应用协议 //http&#xff0c;socket 4、抓包技术应用支持 5、封包技术应用意义 总结点&#xff1a;学会不同对象采用…

数学建模入门——描述性统计分析

摘要&#xff1a;本篇博客主要讲解了数学建模入门的描述性统计分析&#xff0c;包括基本统计量的计算、数据的分布形态、数据可视化和相关性分析。 往期回顾&#xff1a; 数学建模入门——建模流程-CSDN博客 数学建模入门——数据预处理&#xff08;全&#xff09;-CSDN博客 …

遗传学的“正反”之道:探寻生命密码的两把钥匙

正向遗传学 & 反向遗传学 在生活中&#xff0c;我们常常会惊叹于孩子与父母外貌、性格上的相似之处&#xff0c;或是疑惑于某些家族遗传病为何代代相传。其实&#xff0c;这些现象背后都隐藏着遗传学的奥秘。遗传学&#xff0c;作为一门探索生物遗传与变异规律的学科&#…