当前位置: 首页 > news >正文

vue使用html2canvas截图下载时,存在svg或者img或者特殊字体时截图不全的解决办法

使用html2canvas进行div截图时,存在svg和img的解决办法

  • 写在前面:
  • vue使用html2canvas截图时,存在svg或者img或者特殊字体时截图时空白,或者不全
    • 解决办法如下
    • 第一步,svg或者img先转base64(如果是特殊字体,就把这个字体图形截图转base64)
    • 第二步,将转换后的base64设置为新元素的content属性:
    • 第三步,实现div的截图下载

写在前面:

1.网上html2canvas资料少,即使你复制拿来用了,也发现各种问题是不是?
2.它的官网也没有好的demo,不好解决我们的问题。
3.我自己研究了两天,自创魂技,搞定了它。

以下不废话:

vue使用html2canvas截图时,存在svg或者img或者特殊字体时截图时空白,或者不全

如果你的原元素是img,当然再导入canvas,通过img转canvas去替换原来的子节点,再使用html2canvas导出图片。对于组件层级不多的页面是可用的。

 const changeToCanvas = async (element) => {const imgElems = element.querySelectorAll('img')let svgelems = [...imgElems]svgelems.forEach((node) => {let parentNode = node.parentNodelet canvas = document.createElement('canvas')canvas.style.zIndex = 999//处理img转换canvasif (node.tagName == 'IMG') {canvas.width = node.widthcanvas.height = node.heightcanvas.getContext('2d').drawImage(node, 0, 0)parentNode.removeChild(node)let index = parentNode.firstChildif (index != null) {parentNode.insertBefore(canvas, index)} else {parentNode.appendChild(canvas)}}})}

但是如果你组件层级多时,你会发现这种办法不是很好用,容易出现各种意想不到的问题。

如果你的原元素是svg,那么思路是,遍历div内的svg,把svg转图片,遍历图片转canvas再用html2canvas截图,如果你这么做了成功了,图片没有缺失。那么恭喜你,因为大多数都会存在各种问题。

个人认为:除非你的项目很特殊,根本不需要用canvas去把svg转一下,因为转了以后会出现元素位置问题、删除和新增div节点的延时问题等等。下面自创思路就能完美解决问题。

解决办法如下

第一步,svg或者img先转base64(如果是特殊字体,就把这个字体图形截图转base64)

注意:最好是把转之前的图片尺寸先做好,可以用美图秀秀等把图片尺寸修改一下适配你原来的页面,再转base64,这样就省去了调节css的麻烦。
这里我推荐两个网站,可以将你的svg或img转base64

https://www.chahuo.com/svg2css.html#google_vignettehttps://www.bejson.com/image/imgzoom/#google_vignette

第二步,将转换后的base64设置为新元素的content属性:

如下,用新的div的css的content属性代替原来的svg或者img。这样就不需要canvas,只用html2canvas就能实现截图下载。

::v-deep(.vxe-icon-square-minus) {pointer-events: none;&::before {content: url('data:image/svg+xml;base64,PHN2ZyB0PSIxNzE3NDMyMzMzNDEzIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQ4OTAyIiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiPjxwYXRoIGQ9Ik0xMDI0IDB2MTAyNEgwVjBoMTAyNHogbS03OC43NjkyMzEgNzguNzY5MjMxSDc4Ljc2OTIzMXY4NjYuNDYxNTM4aDg2Ni40NjE1MzhWNzguNzY5MjMxeiIgZmlsbD0iIzhhOGE4YSIgcC1pZD0iNDg5MDMiPjwvcGF0aD48cGF0aCBkPSJNNzg3LjY5MjMwOCA0NzIuNjE1Mzg1djc4Ljc2OTIzSDIzNi4zMDc2OTJWNDcyLjYxNTM4NXoiIGZpbGw9IiM4YThhOGEiIHAtaWQ9IjQ4OTA0Ij48L3BhdGg+PC9zdmc+');background-repeat: no-repeat;background-position: center;width: 1em;height: 1em;display: inline-block;}
}::v-deep(.vxe-icon-square-plus) {pointer-events: none;&::before {content: url('data:image/svg+xml;base64,PHN2ZyB0PSIxNzE3NDMyMTAyODAwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQ0MzgwIiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiPjxwYXRoIGQ9Ik0xMDI0IDB2MTAyNEgwVjBoMTAyNHogbS03OC43NjkyMzEgNzguNzY5MjMxSDc4Ljc2OTIzMXY4NjYuNDYxNTM4aDg2Ni40NjE1MzhWNzguNzY5MjMxeiIgZmlsbD0iIzhhOGE4YSIgcC1pZD0iNDQzODEiPjwvcGF0aD48cGF0aCBkPSJNNzg3LjY5MjMwOCA0NzIuNjE1Mzg1djc4Ljc2OTIzSDIzNi4zMDc2OTJWNDcyLjYxNTM4NXoiIGZpbGw9IiM4YThhOGEiIHAtaWQ9IjQ0MzgyIj48L3BhdGg+PHBhdGggZD0iTTQ3Mi42MTUzODUgMjM2LjMwNzY5Mmg3OC43NjkyM3Y1NTEuMzg0NjE2SDQ3Mi42MTUzODV6IiBmaWxsPSIjOGE4YThhIiBwLWlkPSI0NDM4MyI+PC9wYXRoPjwvc3ZnPg==');background-repeat: no-repeat;background-position: center;width: 1em;height: 1em;display: inline-block;}
}
::v-deep(.icon_cri_1) {&::before {content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAA1dJREFUOE9tlE1oXFUUx3/n3TdvPjL5nCQFE7uQSt1owU/iplUxiIpgQVBKoVS7ERQFoZuiaBe1guhCRHHhQty4qOnWhRVawYoKbjTBJB0nE+tk8tF8zsx7994jb8gMIfY+Lu8+zr2/9z/3nvsXdpuqyu6w8+6GOoM98XROAOhu97ILSAMhENU342lENkCWBaz36gVtIe2nCdJS/Eghl/2hGPIxYIFWBxTArd51Bl5q7CTnxUg1NOGKKpEqO0HApmp7wQi4XmfVhaEZ7MvItUzCF2T4patoC4afOfF97YWXJ1Dv0yxUZF+WYgU8+LxWyhu8dWrkp4Fw60xEcbqraBV6jr52c/30cyWG+xpIGIIYxLcIwjy1jTRzRbBk1fFrBd45ma8PN1uP5HK5SgdkPrm82qoVi8HRQxG4bVIthgjxMT2FPMubYBVsIGQSy+xKqJXZqn54+s5iZ4/S3Zf3L8eJDbfl0bsHsXgKoVDMQT50mABaNqThYWEtJrIt5mue3ytGPzheHBgaYidV1Aa9O3UzCXb65OH7s21Q6Dz5wDM6FBHi2dyGfzeaNIICGRtz45+Y65UtvXBivHSwn60u6NzXVZu4LE88NEycNEANxjU5ON6P84pNlMpSA+MNLrBaXlB+vlHnszfvGu6DW13Q2S8XbGwjJidGSGwTNKBUiqgvNTGSp3/QsbzSxPhQrSTMlS3X51f46vVDY4UCte6pvfFp2cYuy+RECSVG1eC9JwgCvPOIqDrnUxBWYubKjh9n6vrNe/fc0QP1jiJe/WjeNq3Is8fGUdeCQPAWcsWCVqqrjA4WSdy2SBIpxvHXfJOrfy7ppYv3HuiFlW5Bnrkwa3dcIk8/NkY+I6hEXLkyS3UpAFNEG1WeP36fGlUJMzHVxUi/+21OL507Mtrby2oHxMm3p+1WojJ57LAslueYmbEauz6SIMaSELqIjMbksuvy5FMPMPXttDaLCVMXjxwownIX9OLZP5LNxARJM9Gs5MEY8UGCoIqmChUllNBGWF1DMv20smv/B71y/trV2mbpQWNzAWpEJYWk6w0qgYo68YEV8VlBbErH+b/jzy88fngsz2L7Vu6xkvQ79ZiO39zOk9J42tJCNrtzm/tBez1sv8G1/3kbk2tbxX8hiskPouecRAAAAABJRU5ErkJggg==');background-repeat: no-repeat;background-position: center;width: 1em;height: 1em;margin-right: 5px;margin-top: 3px;display: inline-block;}
}
::v-deep(.icon_cri) {&::before {content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAzhJREFUOE+FlN1rHGUUxp9z3pn9SHbdmE26TY0Qml6oV0mk0HpTEUQRrZZCaymI4K03/if+AQq90CL4hVVvctEbqai9EIxSKxFqLcY0O/kwye7OvO85R96JW7cUcWAYmDnzm+c85zlD+J/DzOi/SojIhs/KotHid67vvHvrzsbrOVUBAxxCeR0ejD5SpPb80swzJ+caX8XXI3AURCu/7p5evp1/EtIG9a0CgMDQkmEWaWQ5O9TV40hDszeWqkcAhBI0qubytY28Od1MxaUQc6DgUbgEKgY1MxFFbgzyipxSnUP23IuL7asPgD64vhXqE01ujon54E0kQWLGv+2mGHACFjWTKAFQZZ1H98zLx6e+iIrv8+j9b7ohbU3S47NkYyIWrfydE/phVTlnBsQggZADpgJbqGVnX3my/VkJGmmNLn+b+azWptRr6e+uY9RDgVwIhVLpkwXBPtVMATvRyM6dWWp/+gDova83/DaIXliYKhqGUMC8MBVRmZmxN3K9cYQPr0p7R52dmto5f3axFUH3zI4t0qXvtov1MBG9LGfl1SMoI8QQiAFSgISxhxQmYi/N7r16eqH18aiiCOK3l9fyrH6YvMbGGEGAJPSxjzr6BAoCS33AwBxEAp56ePPCm093Phoq4i2geffW1qU/q61nB4xqUHBtjOzGTaUftx1BDWnYx6mF2l61zpWYUGJIax+vPVodXJubHs+i2QzA7eY4urJRfL/Vr6RigqCBwYxmK5UAoFoBsvXgAsdIeA1KmGvquZOzlS/vKYp9dNE79PNa5eZaP3GqcZplNNTEojsEIi7vmDo2ZnHAfEPOn5hxn8e64fhd1kfnl679dLuvNTPzRDA1CIw9gWIckohTwFVUqkSO5luDC4sz9Zijf0FrAzxy566u3BhwDVbGqFxVOlizg4UDODhQTYwckx6dwMXjh3BlFMTdXq+T+cpjf2wWVwjmY1AJxBZFECT2ZjAOxFKXsFegunz4ofStJ6bRu2/8O0CrB7jxGKG/Dj4fL02DWQtx9+OaaTwZoByQWDOL+J+BDD2i9XXUO52yBdrcRKIHWxIHR5OTQLcbMwj9p8ZWV2HHjpWwWKd/A63m4Ba1UDJpAAAAAElFTkSuQmCC');background-repeat: no-repeat;background-position: center;width: 1em;height: 1em;margin-right: 5px;display: inline-block;margin-top: 3px;}
}

第三步,实现div的截图下载

一:html2canvas npm

npm install html2canvas@1.4.1  

二:引入

import html2canvas from 'html2canvas'

三:实现

   // 生成图片const creatImg = async () => {try {const setup = {useCORS: true, // 使用跨域backgroundColor: null,allowTaint: true,logging: true, // 打印日志来检查是否有加载问题background: '#ffffff', // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的async: true, // 是否异步解析和呈现元素scale: 2, // 处理模糊问题// dpi: 1000 // 处理模糊问题scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0scrollX: 0,//过滤不需要截图的元素ignoreElements: (element) => {return element.className === 'vxe-tree--btn-wrapper'}}//找到要截图的div节点,//可以用document.getElementById('aaa')等获取要截图的节点,根据实际情况而定const $image = divImage.value.childNodes[0].childNodes[1]//html2canvas 把div转图片await html2canvas($image, setup).then((canvasimg) => {//图片类型const link = canvasimg.toDataURL('image/png')//图片名称const fileName = 'CRI_History_Image_' + getDate()//导出exportPicture(link, fileName)})} catch (e) {console.log(e)}}// 导出图片const exportPicture = (link, name) => {try {const file = document.createElement('a')file.style.display = 'none'file.download = decodeURI(name)let blob = dataURLtoBlob(link)let url = URL.createObjectURL(blob)file.href = urldocument.body.appendChild(file)file.click()document.body.removeChild(file)} catch (e) {console.log(e)}}//图片转Blob类型,避免浏览器报错const dataURLtoBlob = (dataurl) => {var arr = dataurl.split(',')var mime = arr[0].match(/:(.*?);/)[1]var bstr = atob(arr[1])var n = bstr.lengthvar u8arr = new Uint8Array(n)while (n--) {u8arr[n] = bstr.charCodeAt(n)}return new Blob([u8arr], { type: mime })}

相关文章:

vue使用html2canvas截图下载时,存在svg或者img或者特殊字体时截图不全的解决办法

使用html2canvas进行div截图时,存在svg和img的解决办法 写在前面:vue使用html2canvas截图时,存在svg或者img或者特殊字体时截图时空白,或者不全解决办法如下第一步,svg或者img先转base64(如果是特殊字体&am…...

机器学习----奥卡姆剃刀定律

奥卡姆剃刀定律(Occam’s Razor)是一条哲学原则,通常表述为“如无必要,勿增实体”(Entities should not be multiplied beyond necessity)或“在其他条件相同的情况下,最简单的解释往往是最好的…...

【设计模式】行为型设计模式之 模板方法模式

介绍 GOF 定义 模板方法模式 Template Method Design Pattern :模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中去实现;模板方法在不改变算法整体结构的情况下,可以重新定义算法中的某些步骤。 代码举例 …...

智能合约中断言失败

断言失败: 断言(assert)在智能合约中用于确保内部逻辑的一致性和正确性,但如果使用不当,确实可能导致意外的合约终止或资金锁定。这是因为assert主要用于检测程序内部的错误,例如算法错误或逻辑错误&#…...

flink读取hive写入http接口

目录 0、创建hive数据 1、pom.xml 2、flink代码 3、sink 4、提交任务jar 5、flink-conf.yaml 6、数据接收 flink-1.17.2jdk1.8hive-3.1.3hadoop3.3.6passwordhttp0、创建hive数据 /cluster/hive/bin/beeline !connect jdbc:hive2://ip:10000 create database demo; d…...

【论文阅读】MODELING AND SOLVING THE TRAVELING SALESMAN PROBLEM WITH PRIORITY PRIZES

文章目录 论文基本信息摘要1.引言2. INTEGER QUADRATIC PROGRAM FOR TSPPP3. MIXED INTEGER LINEAR PROGRAMS FOR TSPPP4. TABU SEARCH ALGORITHM FOR TSPPP5. COMPUTATIONAL RESULTS6. CONCLUDING REMARKS补充 论文基本信息 《MODELING AND SOLVING THE TRAVELING SALESMAN P…...

【CS.SE】使用 docker pull confluentinc/cp-kafka 的全面指南

文章目录 1 引言2 准备工作2.1 安装 Docker2.1.1 在 Linux 上安装 Docker2.1.2 在 macOS 上安装 Docker2.1.3 在 Windows 上安装 Docker 2.2 验证 Docker 安装 3 拉取 confluentinc/cp-kafka Docker 镜像3.1 拉取镜像3.2 验证镜像 4 运行 Kafka 容器4.1 启动 ZooKeeper4.2 启动…...

STM32快速入门(ADC数模转换)

STM32快速入门(ADC数模转换) 前言 ADC数模转换存在的意义就是将一些温度传感器、各自数据传感器产生的模拟信号转换成方便识别和计算的数字信号。 导航 图24 通用定时器框图: 图片截取自STM32 F1XX中文参考手册。还是以框图为中心&#x…...

Linux环境在非root用户中搭建(java-tomcat-redis)

注: 本文在内网(离线)环境,堡垒机中搭建,服务器不同可能有所差异,仅供参考 本文安装JDK-20.0.1版本,apache-tomcat-10.1.10版本,redis-6.2.15版本 本文服务器IP假设:192.168.88.133 root用户创建子用户并…...

Unity 之 代码修改材质球贴图

Unity 之 代码修改材质球贴图 代码修改Shader:ShaderGraph:材质球包含属性 代码修改 meshRenderer.material.SetTexture("_Emission", texture);Shader: ShaderGraph: 材质球包含属性 materials[k].HasProperty("…...

spark-3.5.1+Hadoop 3.4.0+Hive4.0 分布式集群 安装配置

Hadoop安装参考: Hadoop 3.4.0HBase2.5.8ZooKeeper3.8.4Hive4.0Sqoop 分布式高可用集群部署安装 大数据系列二-CSDN博客 一 下载:Downloads | Apache Spark 1 下载Maven – Welcome to Apache Maven # maven安装及配置教程 wget https://dlcdn.apache.org/maven/maven-3/3.8…...

Matlab实现GWO-CNN-LSTM-Mutilhead-Att灰狼算法卷积长短期记忆神经网络融合多头注意力机制预测 SCI顶级优化

数据预处理:准备和清理数据,包括数据的加载、特征提取、归一化等。 GWO (灰狼算法) 的实现:根据灰狼算法的原理和公式,编写 MATLAB 代码来初始化灰狼群体、计算适应度函数、更新位置等。 CNN (卷积神经网络) 的构建:使…...

RTKLIB之RTKPLOT画图工具

开源工具RTKLIB在业内如雷贯耳,其中的RTKPLOT最近正在学习,发现其功能之强大,前所未见,打开了新的思路。 使用思博伦GSS7000卫星导航模拟器,PosApp软件仿真一个载具位置 1,RTKPLOT支持DUT 串口直接输出的NMEA数据并…...

本地部署 RAGFlow

本地部署 RAGFlow 0. RAGFlow 是什么?1. 安装 wsl-ubuntu2. (可选)配置清华大学软件源3. 系统更新和安装构建工具4. 安装 Miniconda35. 安装 CUDA Toolkit6. 安装 git lfs7. 配置 Hugging Face 的缓存路径8. 配置 vm.max_map_count9. 安装 Docker Engine10. 安装 nginx11. 本地…...

php常用数据库操作

文章目录 PHP操作1. mysqli_connect() 连接数据库2. mysqli_close() 关闭数据库3. mysqli_num_rows 查询结果集中的行数4. mysqli_select_db 选择数据库的函数5. mysqli_query 常规的插入查找等6. header( )7.防止 sql 注入 PHP操作 1. mysqli_connect() 连接数据库 2. mysql…...

判断经纬度是否在某个城市内

一、从高德获取指定城市边界经纬度信息 通过apifox操作&#xff1a; 二、引入第三方jar包&#xff1a; maven地址&#xff1a;https://mvnrepository.com/ maven依赖&#xff1a; <dependency><groupId>org.locationtech.jts</groupId><artifactId>…...

Java——数组排序和查找

一、排序介绍 1、排序的概念 排序是将多个数据按照指定的顺序进行排列的过程。 2、排序的种类 排序可以分为两大类&#xff1a;内部排序和外部排序。 3、内部排序和外部排序 1&#xff09;内部排序 内部排序是指数据在内存中进行排序&#xff0c;适用于数据量较小的情况…...

Flutter中防抖动和节流策略

什么是防抖和节流&#xff1f; 函数节流&#xff08;throttle&#xff09;与 函数防抖&#xff08;debounce&#xff09;都是为了限制函数的执行频次&#xff0c;以优化函数触发频率过高导致的响应速度跟不上触发频率&#xff0c;出现延迟&#xff0c;假死或卡顿的现象 是应对频…...

设计模式-中介者(调停者)模式(行为型)

中介者模式 中介者模式是一种行为型模式&#xff0c;又叫调停者模式&#xff0c;它是为了解决多个对象之间&#xff0c;多个类之间通信的复杂性&#xff0c;定义一个中介者对象来封装一些列对象之间的交互&#xff0c;使各个对象之间不同持有对方的引用就可以实现交互&#xf…...

HC-05蓝牙模块配置连接和使用

文章目录 1. 前期准备 2. 进入AT模式 3. 电脑串口配置 4. 配置过程 5. 主从机蓝牙连接 6. 蓝牙模块HC-05和电脑连接 1. 前期准备 首先需要准备一个USB转TTL连接器&#xff0c;电脑安装一个串口助手&#xff0c;然后按照下面的连接方式将其相连。 VCCVCCGNDGNDRXDTXDTXD…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...