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

html2canvas + jspdf 纯前端HTML导出PDF的实现与问题

前言

        这几天接到一个需求,富文本编辑器的内容不仅要展示出来,还要实现展示的内容导出pdf文件。一开始导出pdf的功能是由后端来做的,然后发现对于宽度太大的图片,导出的pdf文件里部分图片内容被遮盖了,但在前端是正常显示的,只因为class样式后端无法解析。然后,后端开发人员就嫌麻烦,让前端来实现导出pdf的功能。。。

html2canvas(V1.4.1)

         html2canvas 用于将 html 元素渲染成图像,可以将整个页面或特定区域以图像形式进行捕获。这对于将复杂的 html 结构转换为 PDF 格式非常有用,因为它可以捕获 html 中的样式、布局和图像等细节。

        官网:https://html2canvas.hertzen.com/

引用

npm install html2canvas@1.4.1 --save
或
yarn add html2canvas@1.4.1
或
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>

示例

<template><div id="pdfBody" style="margin: 30px;"><input class="test_input" type="text" autocomplete="off" placeholder="输入框111"/><input class="test_btn" id="testBtn" type="button" value="按钮"/></div>
</template><script>import html2canvas from "@/utils/htmlToPdf/html2canvas.min";export default {name: "Test",mounted() {document.getElementById('testBtn').addEventListener('click', () => {this.canvasTest();});},methods: {createCanvas(dom) {html2canvas(dom, {useCORS: true, //允许跨域scale: 2, //按比例增加分辨率dpi: 200, //将分辨率提高到特定的DPI(每英寸点数)ignoreElements: (e) => {//过滤head、body等无用的标签元素return !(e.contains(dom) || dom.contains(e) || e.tagName === 'STYLE' || e.tagName === 'LINK');},onclone: (doc) => {//Scoped CSS无法直接应用,需要手动处理let inputDocArr = doc.getElementsByClassName('test_input');[].forEach.call(inputDocArr, inputDoc => {inputDoc.style.height = '36px';inputDoc.style.lineheight = '36px';inputDoc.style.width = '200px';inputDoc.style.margin = '20px';inputDoc.style.borderRadius = '5px';inputDoc.style.border = '1px solid #DCDFE6';});let btnDocArr = doc.getElementsByClassName('test_btn');[].forEach.call(btnDocArr, btnDoc => {btnDoc.style.color = '#FFFFFF';btnDoc.style.backgroundColor = '#1890ff';btnDoc.style.border = '1px solid #1890ff';btnDoc.style.height = '36px';btnDoc.style.width = '80px';btnDoc.style.borderRadius = '20px';});}}).then(canvas => {dom.appendChild(canvas);}).finally(() => {console.log('create canvas finish!');});},canvasTest() {let pdfBody = document.getElementById('pdfBody');this.createCanvas(pdfBody);}}}
</script><style scoped>.test_input {height: 36px;line-height: 36px;width: 200px;margin: 20px;border-radius: 5px;border: 1px solid #DCDFE6;}.test_input:focus {border: 1px solid #1890ff;outline: none;}.test_btn {color: #FFFFFF;background-color: #1890ff;border: 1px solid #1890ff;height: 36px;width: 80px;border-radius: 20px;cursor: pointer;}
</style>

 配置项

        如果想隐藏某个元素不让其显示出来,参考以下几种方案:

        1、元素标签添加 data-html2canvas-ignore 属性,示例如下:

        2、配置项中添加 ignoreElements 属性,手动过滤某个元素,示例如上代码;

        3、配置项中添加 onclone 属性,手动处理某个元素的显示与隐藏,即:element.style.display = 'hidden'。

jsPDF(V1.5.3)

         jsPDF 是一个 PDF 生成库,它允许你通过 JavaScript 代码创建和编辑 PDF 文档。

        官网:https://github.com/parallax/jsPDF

引用

npm install jsPDF@1.5.3 --save
或
yarn add jsPDF@1.5.3
或
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>

 示例

<template><div id="pdfBody" style="margin: 30px;"><h3>测试创建pdf文件!</h3><input id="testPdf" type="button" value="pdf测试"/></div>
</template><script>import jsPDF from "@/utils/htmlToPdf/jspdf.min";export default {name: "Test",mounted() {document.getElementById('testPdf').addEventListener('click', () => {this.pdfTest();});},methods: {pdfTest() {let doc = new jsPDF({orientation: 'p',unit: 'mm',format: 'a4'});doc.text("Hello world!", 10, 10);doc.save("测试.pdf");}}}
</script>

设置中文字体

        设置英文内容是正常显示的,假若内容包含中文,会发现pdf文件里的内容显示乱码,如下图所示:

let doc = new jsPDF({orientation: 'p',    unit: 'mm',format: 'a4'
});
doc.text("pdf文件测试!", 10, 10);
doc.save("测试.pdf");

        解决这一问题,可以使用 jsPDF 提供的 setFont(font) 方法,具体操作如下:

        1、网上下载一个支持中文的字体tff文件,或者拷贝一份本地 window/font/ 路径下的字体文件(ps:有的字体不支持);

        2、从GitHub上下载jsPDF源码,然后打开fontconverter目录下的fontconverter.html文件;

        3、选择本地的tff文件,点击“Create”按钮,会生成一个js文件;

        4、一般情况下,生成的js文件直接引入页面使用会报错,需要手动处理生成新的js文件;

        默认生成的js文件内容如下:

(function (jsPDFAPI) {var font = "XXXXXX";var callAddFont = function () {this.addFileToVFS("simfang.ttf", font);this.addFont("simfang.ttf", "simfang", "normal");
};
jsPDFAPI.events.push(['addFonts', callAddFont])})(jsPDF.API);

        然后复制一份js文件,编辑内容如下格式:

export function addfont(pdf) {let font = 'XXXXXX';pdf.addFileToVFS('simfang.ttf', font);pdf.addFont('simfang.ttf', 'simfang', 'normal');
}

        5、将处理好的新的js文件放入项目中,然后在页面中引用,并设置字体。

<template><div id="pdfBody" style="margin: 30px;"><h3>测试创建pdf文件!</h3><input id="testPdf" type="button" value="pdf测试"/></div>
</template><script>import jsPDF from "@/utils/htmlToPdf/jspdf.min";import {addfont} from '@/utils/htmlToPdf/simfang';export default {name: "Test",mounted() {document.getElementById('testPdf').addEventListener('click', () => {this.pdfTest();});},methods: {pdfTest() {let doc = new jsPDF({orientation: 'p',unit: 'mm',format: 'a4'});//设置中文字体addfont(doc);doc.setFont('simfang');doc.text("pdf文件测试撒大大大飒飒热通过如果还有就要让他阿松大尔特瑞特好几年,是否然后他又就很尴尬发射任务给他人用不上,二条天皇已经不是v堵塞惹我实在是肉体和set一年德国必须色让他管很多人把!", 10, 10);doc.save("测试.pdf");}}}
</script>

解决jsPDF文本不自动换行问题

        中文乱码问题解决了,然后新的问题又出现了,文本不自动换行。解决方案参考如下:

        1、使用 splitTextToSize() 方法:

let doc = new jsPDF({orientation: 'p',unit: 'mm',format: 'a4'    
});
//设置中文字体
addfont(doc);
doc.setFont('simfang');
let con = "pdf文件测试撒大大大飒飒热通过如果还有就要让他阿松大尔特瑞特好几年,是否然后他又就很尴尬发射任务给他人用不上,二条天皇已经不是v堵塞惹我实在是肉体和set一年德国必须色让他管很多人把!";
let splitCon = doc.splitTextToSize(con, 190);
console.log('splitCon',splitCon)
doc.text(splitCon, 10, 10);
doc.save("测试.pdf");

        2、text() 方法参数添加选项 maxWidth :

let doc = new jsPDF({orientation: 'p',unit: 'mm',format: 'a4'
});
//设置中文字体
addfont(doc);
doc.setFont('simfang');
let con = "pdf文件测试撒大大大飒飒热通过如果还有就要让他阿松大尔特瑞特好几年,是否然后他又就很尴尬发射任务给他人用不上,二条天皇已经不是v堵塞惹我实在是肉体和set一年德国必须色让他管很多人把!";
doc.text(con, 10, 10, {maxWidth: 190
});
doc.save("测试.pdf");

jsPDF 库 API

        文档地址:https://artskydj.github.io/jsPDF/docs/index.html

        以下是常用API,仅供参考:

方法说明
var doc = new jsPDF(orientation, unit, format, compress);

创建新文档:

orientation:"l"(横向)、"p"(纵向);

unit:"pt"、"mm"(默认)、"cm"、"m"、"in" or "px";

format:"a3"、"a4(默认)"、"a5"、"letter"、"legal"等

doc.addPage()添加一个空白页
doc.setPage(pageNumber)切换到第几个页面操作
doc.internal.getNumberOfPages()获取总页面数
doc.text(text, x, y, options);

页面中添加文本:

text:文本内容;

x:距离页面左边的距离;

y:距离页面上边的距离;

options:可选参数配置

doc.setFont(fontName, fontStyle)

页面文本设置字体:

fontName:字体名称;

fontStyle:字体风格,如"加粗"

doc.setFontSize(size);设置字体大小
doc.setTextColor(ch1, ch2, ch3, ch4);设置文本颜色,可以是颜色码或rgb值
doc.addImage(imageData,format, x, y, width, height)

在 PDF 文件中添加一个图像:

imageData:图像的数据;

format:图像的类型,如"JPEG";

x、y:分别表示图像左上角的坐标;

width:图像的宽度;

height:图像的高度

doc.save(filename)生成指定文件名的PDF文件

html2canvas + jsPDF

        jsPDF 与 html2canvas 结合使用,可以将 html 元素渲染成图像,然后将图像插入到 jsPDF 创建的 PDF 文档中。

示例

import html2canvas from "@/utils/htmlToPdf/html2canvas.min";
import jsPDF from "@/utils/htmlToPdf/jspdf.min";
import {addfont} from '@/utils/htmlToPdf/simfang';
import {Loading} from "element-ui";export function downloadPdf(title, dom) {let reqLoading = Loading.service({fullscreen: true,text: '正在生成PDF文件......',spinner: 'el-icon-loading',background: 'rgba(0,0,0,0.5)'});html2canvas(dom, {useCORS: true, //允许跨域scale: 2, //按比例增加分辨率dpi: 200, //将分辨率提高到特定的DPI(每英寸点数)ignoreElements: (e) => {return !(e.contains(dom) || dom.contains(e) || e.tagName === 'STYLE' || e.tagName === 'LINK');}}).then(canvas => {// dom.appendChild(canvas);// 新建JsPDF对象let PDF = new jsPDF({orientation: 'p', //参数: l:横向  p:纵向unit: 'mm', //参数:测量单位("pt","mm", "cm", "m", "in" or "px")format: 'a4', //A4纸});let ctx = canvas.getContext('2d');let a4w = 190;let a4h = 272; //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277,底部留5mm的页码显示位置,所以高度为272mm。let imgHeight = Math.floor(a4h * canvas.width / a4w) - 2; //按A4显示比例换算一页图像的像素高度let renderedHeight = 0;//计算总页数let pageCount = Math.ceil(canvas.height / imgHeight);let page = document.createElement("canvas");page.width = canvas.width;//设置中文字体addfont(PDF);PDF.setFont('simfang');while (renderedHeight < canvas.height) {page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页//用getImageData剪裁指定区域,并画到前面创建的canvas对象中page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);//canvas转图片数据保留10mm边距PDF.addImage(page.toDataURL('image/jpeg', 1), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width));renderedHeight += imgHeight;//计算当前页及文字let pageNumberText = '第' + (renderedHeight / imgHeight) + '页/共' + pageCount + '页';//设置文字大小PDF.setFontSize(4);//设置文字颜色PDF.setTextColor('#999');//在页脚添加页码PDF.text(pageNumberText, ((a4w + 8) / 2), (a4h + 16));//判断是否分页,如果后面还有内容,添加一个空页if (renderedHeight < canvas.height) {PDF.addPage();}}PDF.save(title + ".pdf");}).finally(() => {if (reqLoading) {reqLoading.close();}});
}

常见问题

截取的图片显示空白

1、跨域问题

        html2canvas 默认是不支持跨域图片的,对于跨域的图片默认是无法截取进去的,需要开启跨域配置:

  1. 将图片转成 base64 形式;
  2. 设置配置项 allowTaint: true 或 useCORS: true;
  3. img 标签中添加 crossOrigin="anonymous";
  4. 图片服务器配置 Access-Control-Allow-Origin: *

2、图片未加载完成

        若图片未加载完成,此时截取的也是空白,解决方法就是设置延时一定事件后处理,或图片添加 load 事件,等图片加载完在进行截图。

3、需要截图的dom元素太多

        若出现前面内容都正常截取,后面内容出现空白,大概率就是dom元素太多了。本人就碰到这种情况,即使延时10秒后截取,后面的部分还是空白,没办法,最后只能后端实现导出pdf功能了。。。

截图后部分css效果未正常显示

1、部分css样式 html2canvas 不支持

        html2canvas 无法支持全部的css样式,关于支持哪些css样式或不支持哪些css样式,可以参考文档:https://html2canvas.hertzen.com/features

2、scoped 作用域的css无法应用

        在vue中,为了避免css样式的交叉污染,都会使用 scoped 作用域的css样式,但是该作用域下的css样式无法在 html2canvas 中使用,解决方案可以在 onclone 配置项中过滤元素手动处理样式(详情可参考上述示例)

        其他的问题可以参考博文:https://www.cnblogs.com/padding1015/p/9225517.html

总结

        使用 html2canvas + jsPDF 纯前端导出pdf的方式还是有很多问题的,一般情况下都是后端进行文件的导出,前端配合解决样式问题。

        另外我看还有使用 dom-to-image 或 modern-screenshot 的,不知道效果怎么样,有时间可以试一下。

相关文章:

html2canvas + jspdf 纯前端HTML导出PDF的实现与问题

前言 这几天接到一个需求&#xff0c;富文本编辑器的内容不仅要展示出来&#xff0c;还要实现展示的内容导出pdf文件。一开始导出pdf的功能是由后端来做的&#xff0c;然后发现对于宽度太大的图片&#xff0c;导出的pdf文件里部分图片内容被遮盖了&#xff0c;但在前端是正常显…...

【JVM】JVM调优练习-随笔

JVM实战笔记-随笔 前言字节码如何查看字节码文件jclasslibJavapArthasArthurs监控面板Arthus查看字节码信息 内存调优内存溢出的常见场景解决内存溢出发现问题Top命令VisualVMArthas使用案例 Prometheus Grafana案例 堆内存情况对比内存泄漏的原因:代码中的内存泄漏并发请求问…...

如何解决 CentOS 7 官方 yum 仓库无法使用

一、背景介绍 编译基于 CentOS 7.6.1810 镜像的 Dockerfile 过程中,执行 yum install 指令时,遇到了错误:Could not resolve host: mirrorlist.centos.org; Unknown error。 二、原因分析 官方停止维护 CentOS 7。该系统内置的 yum.repo 所使用的域名 mirrorlist.centos.o…...

分布式唯一id的7种方案

背景 为什么需要使用分布式唯一id&#xff1f; 如果我们的系统是单体的&#xff0c;数据库是单库&#xff0c;那无所谓&#xff0c;怎么搞都行。 但是如果系统是多系统&#xff0c;如果id是和业务相关&#xff0c;由各个系统生成的情况下&#xff0c;那每个主机生成的主键id就…...

嵌入式物联网在医疗行业中的应用——案例分析

作者主页: 知孤云出岫 目录 嵌入式物联网在医疗行业中的应用——案例分析引言1. 智能病房监控1.1 实时患者监控系统 2. 智能医疗设备管理2.1 设备使用跟踪与维护 3. 智能药物管理3.1 药物分配与跟踪 4. 智能远程医疗4.1 远程患者监控与诊断 总结 嵌入式物联网在医疗行业中的应…...

C语言 底层逻辑详细阐述指针(一)万字讲解 #指针是什么? #指针和指针类型 #指针的解引用 #野指针 #指针的运算 #指针和数组 #二级指针 #指针数组

文章目录 前言 序1&#xff1a;什么是内存&#xff1f; 序2&#xff1a;地址是怎么产生的&#xff1f; 一、指针是什么 1、指针变量的创建及其意义&#xff1a; 2、指针变量的大小 二、指针的解引用 三、指针类型存在的意义 四、野指针 1、什么是野指针 2、野指针的成因 a、指…...

【人工智能大模型】文心一言介绍以及基本使用指令

目录 一、产品背景与技术基础 二、主要功能与特点 基本用法 指令的使用 注意事项 文心一言&#xff08;ERNIE Bot&#xff09;是百度基于其文心大模型技术推出的生成式AI产品。以下是对文心一言的详细介绍&#xff1a; 一、产品背景与技术基础 技术背景&#xff1a;百度…...

AI绘画入门实践|Midjourney 的模型版本

模型分类 Midjourney 的模型主要分为2大类&#xff1a; 默认模型&#xff1a;目前包括&#xff1a;V1, V2, V3, V4, V5.0, V5.1, V5.2, V6 NIJI模型&#xff1a;目前包括&#xff1a;NIJI V4, NIJI V5, NIJI V6 模型切换 你在服务器输入框中输入 /settings&#xff1a; 回车后…...

Web3时代的教育技术革新:智能合约在学习管理中的应用

随着区块链技术的发展和普及&#xff0c;Web3时代正在为教育技术带来前所未有的革新和机遇。智能合约作为区块链技术的核心应用之一&#xff0c;不仅在金融和供应链管理等领域展示了其巨大的潜力&#xff0c;也在教育领域中逐渐探索和应用。本文将探讨智能合约在学习管理中的具…...

云计算实训室的核心功能有哪些?

在当今数字化转型浪潮中&#xff0c;云计算技术作为推动行业变革的关键力量&#xff0c;其重要性不言而喻。唯众&#xff0c;作为教育实训解决方案的领先者&#xff0c;深刻洞察到市场对云计算技能人才的迫切需求&#xff0c;精心打造了云计算实训室。这一实训平台不仅集成了先…...

芯科科技第五届物联网开发者大会走进世界各地,巡回开启注册

中国&#xff0c;北京 – 2024年7月18日 – 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;今日宣布&#xff0c;其2024年Works With开发者大会现正开放注册…...

Python创建Excel表和读取Excel表的基础操作

下载openpyxl第三方库 winr打开命令行输入cmd 这个如果不行可以试试其他方法&#xff0c;在运行Python代码的软件里也有直接下载的地方&#xff0c;可以上网搜索 创建Excel表 示例代码&#xff1a;最后要记得保存&#xff0c;可以加一句提示语句。 import openpyxl lst[100,…...

JVM(day2)经典垃圾收集器

经典垃圾收集器 Serial收集 使用一个处理器或一条收集线程去完成垃圾收集工作&#xff0c;更重要的是强调在它进行垃圾收集时&#xff0c;必须暂停其他所有工作线程&#xff0c;直到它收集结束。 ParNew收集器 ParNew 收集器除了支持多线程并行收集之外&#xff0c;其他与 …...

华为od机试真题 — 分披萨(Python)

题目描述 “吃货”和“馋嘴”两人到披萨店点了一份铁盘(圆形)披萨&#xff0c;并嘱咐店员将披萨按放射状切成大小相同的偶数个小块。 但是粗心服务员将披萨切成了每块大小都完全不同奇数块&#xff0c;且肉眼能分辨出大小。 由于两人都想吃到最多的披萨&#xff0c;他们商量…...

ubuntu22.04 安装boost

下载boost压缩包&#xff0c;我这里上传了一份1_81_0版本tar -xzvf boost_1_81_0.tar.gzcd boost_1_81_0/sudo apt install build-essential g autotools-dev libicu-dev libbz2-dev -ysudo ./bootstrap.sh --prefix/usr/./b2sudo ./b2 install 上述7步完成后&#xff0c;相关…...

基于JAVA+SpringBoot+uniapp的心理小程序(小程序版本)

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、SpringCloud、Layui、Echarts图表、Nodejs、爬…...

C语言 ——— 输入两个正整数,求出最小公倍数

目录 何为最小公倍数 题目要求 代码实现 方法一&#xff1a;暴力求解法&#xff08;不推荐&#xff09; 方法二&#xff1a;递乘试摸法&#xff08;推荐&#xff09; 何为最小公倍数 最小公倍数是指两个或者多个正整数&#xff08;除了0以外&#xff09;的最小的公共倍数…...

Langchain 对pdf,word,txt等不同文件的加载解析

项目中遇到各种数据资源想要加载近langchain构建本地知识ai系统&#xff0c;怎么加载对应的文件格式呢&#xff0c;一起研究下 引入Langchain from langchain.document_loaders import UnstructuredWordDocumentLoader,PyPDFium2Loader,DirectoryLoader,PyPDFLoader,TextLoad…...

BL201分布式I/O耦合器连接Profinet网络

钡铼技术的BL201分布式I/O耦合器是一个用于Profinet网络的设备&#xff0c;用于连接远程输入/输出&#xff08;I/O&#xff09;设备到控制系统&#xff0c;如可编程逻辑控制器&#xff08;PLC&#xff09;&#xff0c;能够实现分布式的I/O连接和通信。 它支持标准Profinet IO …...

Pycharm 报错 Environment location directory is not empty 解

删除项目中ven文件夹&#xff08;已存在的&#xff09;&#xff0c;然后再添加新的ven虚拟环境就可以了...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...