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

vue3集成LuckySheet实现导入本地Excel进行在线编辑,以及导出功能

第一步:克隆或者下载下面的代码

git clone https://github.com/dream-num/Luckysheet.git

第二步:安装依赖

npm install
npm install gulp -g  

第三步:运行

npm run dev

效果如下图所示
在这里插入图片描述
第四步:打包
打包执行成功后,在文件夹目录下会出现dis文件夹,如下图所示:

npm run build

在这里插入图片描述
第五步:本地引入

把dist文件夹中的代码全部复制粘贴到你项目的public文件夹中,index.html文件除外。在你项目的index.html文件中引入如下代码,如果你复制的位置是其他地方,需要用绝对路径引入这些文件。
<link rel='stylesheet' href='./public/plugins/css/pluginsCss.css' />
<link rel='stylesheet' href='./public/plugins/plugins.css' />
<link rel='stylesheet' href='./public/css/luckysheet.css' />
<link rel='stylesheet' href='./public/assets/iconfont/iconfont.css' />
<script src="./public/plugins/js/plugin.js"></script>
<script src="./public/luckysheet.umd.js"></script>		

接下来就是在项目中使用这个插件
首先要引入luckyexcel 的依赖,我们导入导出本地excel会用到

 npm install luckyexcel --save如果引入依赖报错可能是依赖冲突,可以使用下面的npm install luckyexcel --save --force

然后创建一个vue页面文件

<template><div><div style="height: 10px;position: absolute"><el-uploadref="upload"class="upload-demo"action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15":limit="1":on-change="handleFileChange":auto-upload="false"accept=".xlsx"><template #trigger><el-button type="primary">select file</el-button></template></el-upload></div><div v-if="isShow" id="luckysheet" class="luckysheet-wrap"></div></div>
</template><script setup>
import { ref, onMounted } from 'vue';
import LuckyExcel from 'luckyexcel';
import {ElMessage} from "element-plus";const isShow = ref(false)function handleFileChange(file, newFileList) {const selectedFile = file.raw;if (!(selectedFile instanceof File)) {console.error('传入了非文件对象');return;}if (selectedFile.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {console.log('文件是xlsx类型');} else {console.error('不是xlsx文件');ElMessage.error('请选择xlsx类型文件')return;}let filename = selectedFile.name.replace(/\.[^/.]+$/, ""); // 去除文件扩展名let reader = new FileReader();reader.onload = async (e) => {let fileData = e.target.result;try {isShow.value = trueLuckyExcel.transformExcelToLucky(fileData, async (exportJson, luckysheetfile) => {console.log(exportJson.sheets)creatExcel(filename, JSON.stringify(exportJson.sheets))});} catch (e) {console.error(e);}};reader.onerror = function() {console.error("File could not be read! Code " + reader.error.code);};reader.readAsArrayBuffer(selectedFile);
}function creatExcel(title, content){const options = {container: 'luckysheet', // 设定DOM容器的idtitle: 'excel 表格', // 设定表格名称lang: 'zh', // 设定表格语言hook: {updated: (e) => {//监听更新,并在1s后自动保存$('#luckysheet_info_detail_save').text("已修改")let title = $('#luckysheet_info_detail_input').val();let content = luckysheet.getAllSheets();//去除临时数据,减小体积for (let i in content)content[i].data = undefinedconsole.log(title)console.log(content)}},}options.data = JSON.parse(content)options.title = title;window.luckysheet.create(options)
}onMounted(() => {});
</script><style scoped>
.luckysheet-wrap {margin: 0px;padding: 0px;position: absolute;width: 100%;height: 100%;left: 0px;top: 0px;
}
</style>

在这里插入图片描述
点击按钮选择一个xlsx文件就能导入成功了,效果如下(这里只能导入xlsx文件,导入xls文件会报错,暂时不知道什么原因,如果有xls文件的话可以把表格另存为xlsx类型的文件再导入)
在这里插入图片描述
下面放一个完整的demo展示效果

<template><div style="width: 100%; height: 100vh;overflow: auto;"><div><div style="display: flex;"><div style="margin-right: 10px;"><el-upload ref="upload" :auto-upload="false" accept=".xlsx" :show-file-list='false' :on-change="handleChangeUpload"action="#" class="upload-demo" multiple><el-button type="primary">导入</el-button></el-upload></div><el-button type="primary" @click="goBack()">返回</el-button></div></div><span>电源配线图</span><el-table :data="dataList" width="100%" border :max-height="750"><el-table-column label="序号" align="center" key="id" prop="id" fixed width="100px" /><el-table-column label="模板名称" align="left" key="name" prop="name"/><el-table-column label="导入时间" align="center" key="addTime" prop="addTime"/><el-table-column label="编辑时间" align="center" key="upTime" prop="upTime"/><el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right"><template #default="scope"><el-button link type="primary" icon="Edit" @click="updateData(scope.row)">编辑</el-button><el-button link type="primary" icon="Delete" @click="deleteData(scope.row)">删除</el-button></template></el-table-column></el-table><paginationv-show="total > 0":total="total"v-model:page="pageNum"v-model:limit="pageSize"@pagination="getDataList":page-sizes="[5, 10, 20, 50]"/></div>
</template><script setup>import {onBeforeUnmount, ref} from "vue";
import {ElMessage} from "element-plus";
import {closeWindow, openCenteredWindow, verifyCommand} from "../../openWindow";
import {useRouter} from "vue-router";
import {deletePower, importPower, selectPowerList} from "../../../../api/draw/power";
import LuckyExcel from 'luckyexcel';const {proxy} = getCurrentInstance();
const router = useRouter();const dataList = ref([])const total = ref(0)
const pageNum = ref(1)
const pageSize = ref(10)//查询数据
function getDataList(){selectPowerList({pageNum: pageNum.value,pageSize: pageSize.value}).then(result => {dataList.value = result.rowstotal.value = result.total})
}//删除数据
async function deleteData(row){if ( await verifyCommand() ){proxy.$confirm('确定删除吗?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {let data = {id: row.id,}deletePower(data).then(res=>{if (res.code === 200){getDataList()ElMessage.success('删除成功!');}else {ElMessage.error('删除失败')}})}).catch(() => {proxy.$message({type: 'info',message: '取消删除'});});}
}//编辑按钮
function updateData(row){router.push({name: 'excel',state: {id: row.id,title: row.name,content: row.content,}});
}function handleChangeUpload(file) {const selectedFile = file.raw;if (!(selectedFile instanceof File)) {console.error('传入了非文件对象');return;}if (selectedFile.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {console.log('文件是xlsx类型');} else {console.error('不是xlsx文件');ElMessage.error('请选择xlsx类型文件')return;}let filename = selectedFile.name.replace(/\.[^/.]+$/, ""); // 去除文件扩展名let reader = new FileReader();reader.onload = async (e) => {let fileData = e.target.result;try {LuckyExcel.transformExcelToLucky(fileData, async (exportJson, luckysheetfile) => {console.log(exportJson.sheets)//更改配置中的行数为当前最大行//exportJson.sheets[0].config.rowlen = exportJson.sheets[0].celldata[exportJson.sheets[0].celldata.length-1].r+2let data = {name: filename,content: JSON.stringify(exportJson.sheets)}importPower(data).then(res=>{if (res.code === 200){getDataList()ElMessage.success('导入成功')}else {ElMessage.error(res.msg)}})});} catch (e) {console.error(e);}};reader.onerror = function() {console.error("File could not be read! Code " + reader.error.code);};reader.readAsArrayBuffer(selectedFile);
}onBeforeUnmount (() => {closeWindow();
});// 监听页面即将刷新的事件
window.addEventListener('beforeunload', function (event) {closeWindow();
});const goBack = () => {router.go(-1); // 返回上一页
};getDataList();
</script><style scoped></style>

在这里插入图片描述

<template><div><div id="luckysheet" class="luckysheet-wrap"></div></div>
</template><script setup>
import { ref, onMounted } from 'vue';
import {ElMessage} from "element-plus";
import {updatePower} from "../../../api/draw/power";onMounted(() => {setExcelData();setExcelStyle();
});//对表格数据进行渲染
function setExcelData(){let title = history.state.title;let content = history.state.content;const options = {container: 'luckysheet', // 设定DOM容器的idtitle: 'excel 表格', // 设定表格名称lang: 'zh', // 设定表格语言hook: {updated: (e) => {//监听更新,并在1s后自动保存$('#luckysheet_info_detail_save').text("已修改")let title = $('#luckysheet_info_detail_input').val();let content = luckysheet.getAllSheets();//去除临时数据,减小体积for (let i in content)content[i].data = undefined}},}options.data = JSON.parse(content)options.title = title;window.luckysheet.create(options)
}//对默认表格的样式进行修改
function setExcelStyle(){//去除左上角logolet leftLogo = document.querySelector('.luckysheet-share-logo');leftLogo.className = '';//去除左上角返回按钮let leftButton = document.getElementById('luckysheet_info_detail_title');leftButton.remove();// 创建一个新的保存按钮let newDiv = document.createElement('div');newDiv.innerHTML = '保存';newDiv.style.cursor = 'pointer'newDiv.addEventListener('click', function() {saveData();});let firstChild = document.querySelector('#luckysheet_info_detail').firstElementChild;document.querySelector('#luckysheet_info_detail').insertBefore(newDiv, firstChild);
}//保存数据
function saveData(){let title = $('#luckysheet_info_detail_input').val();let content = luckysheet.getAllSheets();//去除临时数据,减小体积for (let i in content)content[i].data = undefined//更改配置中的行数为当前最大行content[0].config.rowlen = content[0].celldata[content[0].celldata.length-1].r+2let id = history.state.idlet data = {id: id,name: title,content: JSON.stringify(content)}updatePower(data).then(res=>{if (res.code === 200){history.state.title = title;history.state.content = JSON.stringify(content);ElMessage.success('保存成功!');}else {ElMessage.error('保存失败')}})
}
</script><style scoped>
.luckysheet-wrap {margin: 0px;padding: 0px;position: absolute;width: 100%;height: 100%;left: 0px;top: 0px;
}
</style>

在这里插入图片描述
接下来是导出为本地excel
首先在项目中创建export.js文件

// import { createCellPos } from './translateNumToLetter'
import Excel from 'exceljs'import FileSaver from 'file-saver'const exportExcel = function(luckysheet, value) {// 参数为luckysheet.getluckysheetfile()获取的对象// 1.创建工作簿,可以为工作簿添加属性const workbook = new Excel.Workbook()// 2.创建表格,第二个参数可以配置创建什么样的工作表if (Object.prototype.toString.call(luckysheet) === '[object Object]') {luckysheet = [luckysheet]}luckysheet.forEach(function(table) {if (table.data.length === 0) return  true// ws.getCell('B2').fill = fills.const worksheet = workbook.addWorksheet(table.name)const merge = (table.config && table.config.merge) || {}const borderInfo = (table.config && table.config.borderInfo) || {}//设置单元格宽度// 3.设置单元格合并,设置单元格边框,设置单元格样式,设置值setStyleAndValue(table.data, worksheet)setMerge(merge, worksheet)setBorder(borderInfo, worksheet)return true})// return// 4.写入 bufferconst buffer = workbook.xlsx.writeBuffer().then(data => {// console.log('data', data)const blob = new Blob([data], {type: 'application/vnd.ms-excel;charset=utf-8'})console.log("导出成功!")FileSaver.saveAs(blob, `${value}.xlsx`)})return buffer
}var setMerge = function(luckyMerge = {}, worksheet) {const mergearr = Object.values(luckyMerge)mergearr.forEach(function(elem) {// elem格式:{r: 0, c: 0, rs: 1, cs: 2}// 按开始行,开始列,结束行,结束列合并(相当于 K10:M12)worksheet.mergeCells(elem.r + 1,elem.c + 1,elem.r + elem.rs,elem.c + elem.cs)})
}var setBorder = function(luckyBorderInfo, worksheet) {if (!Array.isArray(luckyBorderInfo)) return// console.log('luckyBorderInfo', luckyBorderInfo)luckyBorderInfo.forEach(function(elem) {// 现在只兼容到borderType 为range的情况// console.log('ele', elem)if (elem.rangeType === 'range') {let border = borderConvert(elem.borderType, elem.style, elem.color)let rang = elem.range[0]// console.log('range', rang)let row = rang.rowlet column = rang.columnfor (let i = row[0] + 1; i < row[1] + 2; i++) {for (let y = column[0] + 1; y < column[1] + 2; y++) {worksheet.getCell(i, y).border = border}}}if (elem.rangeType === 'cell') {// col_index: 2// row_index: 1// b: {//   color: '#d0d4e3'//   style: 1// }const { col_index, row_index } = elem.valueconst borderData = Object.assign({}, elem.value)delete borderData.col_indexdelete borderData.row_indexlet border = addborderToCell(borderData, row_index, col_index)// console.log('bordre', border, borderData)worksheet.getCell(row_index + 1, col_index + 1).border = border}// console.log(rang.column_focus + 1, rang.row_focus + 1)// worksheet.getCell(rang.row_focus + 1, rang.column_focus + 1).border = border})
}
var setStyleAndValue = function(cellArr, worksheet) {worksheet.columns = []if (!Array.isArray(cellArr)) returncellArr.forEach(function(row, rowid) {row.every(function(cell, columnid) {if (!cell) return truelet fill = fillConvert(cell.bg)let font = fontConvert(cell.ff,cell.fc,cell.bl,cell.it,cell.fs,cell.cl,cell.ul)let alignment = alignmentConvert(cell.vt, cell.ht, cell.tb, cell.tr)let value = ''if (cell.f) {value = { formula: cell.f, result: cell.v }} else if (!cell.v && cell.ct && cell.ct.s) {// xls转为xlsx之后,内部存在不同的格式,都会进到富文本里,即值不存在与cell.v,而是存在于cell.ct.s之后// value = cell.ct.s[0].vcell.ct.s.forEach(arr => {value += arr.v})} else {value = cell.v}//  style 填入到_value中可以实现填充色let letter = createCellPos(columnid)let target = worksheet.getCell(letter + (rowid + 1))// console.log('1233', letter + (rowid + 1))for (const key in fill) {target.fill = fillbreak}target.font = fonttarget.alignment = alignmenttarget.value = valuesetColumnsWidth(worksheet, rowid)return true})})
}var fillConvert = function(bg) {if (!bg) {return {}}// const bgc = bg.replace('#', '')let fill = {type: 'pattern',pattern: 'solid',fgColor: { argb: bg.replace('#', '') }}return fill
}var fontConvert = function(ff = 0,fc = '#000000',bl = 0,it = 0,fs = 10,cl = 0,ul = 0
) {// luckysheet:ff(样式), fc(颜色), bl(粗体), it(斜体), fs(大小), cl(删除线), ul(下划线)const luckyToExcel = {0: '微软雅黑',1: '宋体(Song)',2: '黑体(ST Heiti)',3: '楷体(ST Kaiti)',4: '仿宋(ST FangSong)',5: '新宋体(ST Song)',6: '华文新魏',7: '华文行楷',8: '华文隶书',9: 'Arial',10: 'Times New Roman ',11: 'Tahoma ',12: 'Verdana',num2bl: function(num) {return num === 0 ? false : true}}// 出现Bug,导入的时候ff为luckyToExcel的vallet font = {name: typeof ff === 'number' ? luckyToExcel[ff] : ff,family: 1,size: fs,color: { argb: fc.replace('#', '') },bold: luckyToExcel.num2bl(bl),italic: luckyToExcel.num2bl(it),underline: luckyToExcel.num2bl(ul),strike: luckyToExcel.num2bl(cl)}return font
}var alignmentConvert = function(vt = 'default',ht = 'default',tb = 'default',tr = 'default'
) {// luckysheet:vt(垂直), ht(水平), tb(换行), tr(旋转)const luckyToExcel = {vertical: {0: 'middle',1: 'top',2: 'bottom',default: 'top'},horizontal: {0: 'center',1: 'left',2: 'right',default: 'left'},wrapText: {0: false,1: false,2: true,default: false},textRotation: {0: 0,1: 45,2: -45,3: 'vertical',4: 90,5: -90,default: 0}}let alignment = {vertical: luckyToExcel.vertical[vt],horizontal: luckyToExcel.horizontal[ht],wrapText: luckyToExcel.wrapText[tb],textRotation: luckyToExcel.textRotation[tr]}return alignment
}var borderConvert = function(borderType, style = 1, color = '#000') {// 对应luckysheet的config中borderinfo的的参数if (!borderType) {return {}}const luckyToExcel = {type: {'border-all': 'all','border-top': 'top','border-right': 'right','border-bottom': 'bottom','border-left': 'left'},style: {0: 'none',1: 'thin',2: 'hair',3: 'dotted',4: 'dashDot', // 'Dashed',5: 'dashDot',6: 'dashDotDot',7: 'double',8: 'medium',9: 'mediumDashed',10: 'mediumDashDot',11: 'mediumDashDotDot',12: 'slantDashDot',13: 'thick'}}let template = {style: luckyToExcel.style[style],color: { argb: color.replace('#', '') }}let border = {}if (luckyToExcel.type[borderType] === 'all') {border['top'] = templateborder['right'] = templateborder['bottom'] = templateborder['left'] = template} else {border[luckyToExcel.type[borderType]] = template}// console.log('border', border)return border
}function addborderToCell(borders, row_index, col_index) {let border = {}const luckyExcel = {type: {l: 'left',r: 'right',b: 'bottom',t: 'top'},style: {0: 'none',1: 'thin',2: 'hair',3: 'dotted',4: 'dashDot', // 'Dashed',5: 'dashDot',6: 'dashDotDot',7: 'double',8: 'medium',9: 'mediumDashed',10: 'mediumDashDot',11: 'mediumDashDotDot',12: 'slantDashDot',13: 'thick'}}// console.log('borders', borders)for (const bor in borders) {// console.log(bor)if (borders[bor].color.indexOf('rgb') === -1) {border[luckyExcel.type[bor]] = {style: luckyExcel.style[borders[bor].style],color: { argb: borders[bor].color.replace('#', '') }}} else {border[luckyExcel.type[bor]] = {style: luckyExcel.style[borders[bor].style],color: { argb: borders[bor].color }}}}return border
}function createCellPos(n) {let ordA = 'A'.charCodeAt(0)let ordZ = 'Z'.charCodeAt(0)let len = ordZ - ordA + 1let s = ''while (n >= 0) {s = String.fromCharCode((n % len) + ordA) + sn = Math.floor(n / len) - 1}return s
}function setColumnsWidth(worksheet, index){const border = {top: {style: 'thin',},left: {style: 'thin',},bottom: {style: 'thin',},right: {style: 'thin',},}worksheet.columns.map((column) => {// 表头的样式worksheet.getCell(`${column.letter}1`).border = borderworksheet.getCell(`${column.letter}1`).font = {bold: true,}worksheet.getCell(`${column.letter}1`).fill = {type: 'pattern',pattern: 'solid',// fgColor: { argb: 'FF8FBC8F' }, //表头背景色}// 列宽自适应let width = []column.values.map((value) => {if (!value) {width.push(10)} else if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {width.push(parseFloat(value.toString().length * 2.15))} else {width.push(parseFloat(value.toString().length * 1.15))}})column.width = Math.max(...width)// 行数据的样式worksheet.getCell(`${column.letter}${index + 2}`).border = border})
}export {exportExcel
}

然后在页面中写一个导出按钮,调用方法

import { exportExcel } from './export'function exportMyExcel(){let title = $('#luckysheet_info_detail_input').val();exportExcel(window.luckysheet.getAllSheets(), title)
}

最后点击导出按钮调用方法,浏览器就会弹出下载excel的窗口(如果是谷歌浏览器可能不会弹出窗口而是直接下载了,可以点击浏览器右上角的下载按钮查看)

ps:注意事项
在导出文件时,如果需要将导出的数据通过接口传输给后端,需要进行文件格式的转换,以file为例。

//获取buffer的
workbook.xlsx.writeBuffer()
.then((arrayBuffer) => {const blob = new Blob(arrayBuffer, {//导出为xlsx文件格式type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});//转为file格式let file = new File([blob], '导出.xlsx', {type: blob.type});/**这里调用接口上传代码*/}).catch(err=>{dialogVisible.value = false})

相关文章:

vue3集成LuckySheet实现导入本地Excel进行在线编辑,以及导出功能

第一步&#xff1a;克隆或者下载下面的代码 git clone https://github.com/dream-num/Luckysheet.git第二步&#xff1a;安装依赖 npm install npm install gulp -g 第三步&#xff1a;运行 npm run dev效果如下图所示 第四步&#xff1a;打包 打包执行成功后&#xff0c;…...

【征求意见】同济大学--城镇给水厂碳排放核算与评价方法

城镇给水厂保障城镇居民正常生活&#xff0c;是社会经济良性发展的重要基础性设施&#xff0c;对于我国双碳战略目标的实现至关重要。 随着城镇化的发展&#xff0c;城镇供水量不断升高&#xff0c;加上 水资源与生态环境问题不断涌现&#xff0c;人们对水的安全和品质的需求日…...

【Python】后台开发返回方法和状态码类的实现

Python 后台开发中&#xff0c;获取返回的类方法&#xff0c;以及状态码类的实现 代码备份 Code - response.py """ Response class for quick generate response """ from loguru_logger import get_loggerlogger get_logger(__name__)clas…...

opencloudosV8.6和openEuler 24安装 k8s

在三台机器上部署 Kubernetes 集群 1.环境准备2.在所有节点上进行以下步骤1. 更新系统和安装必要的软件包2. 禁用交换分区3. 禁用防火墙和SElinux4.系统主机名5.设置主机名与IP地址解析6.配置内核转发及网桥过滤7. 配置 Docker Cgroup 驱动8. 添加 Kubernetes 仓库并安装 kubea…...

Tensor安装和测试

1: 打开git官方 https://github.com/NVIDIA/TensorRT 2: 下载得到&#xff1a;TensorRT-10.2.0.19.Linux.x86_64-gnu.cuda-11.8.tar.gz 3: 下载后配置环境变量&#xff0c;上面地址记得改成真实地址。 4: 如果想python使用tensorrt&#xff0c;那么 解压后目录&#xff0c…...

ELK对业务日志进行收集

ELK对业务日志进行收集 下载httpd 进到文件设置收集httpd的文件进行 设置 编辑内容 用于收集日志的内容 将日志的内容发送到实例当中 input {file{path > /etc/httpd/logs/access_logtype > "access"start_position > "beginning"}file{path &g…...

新质生产力

新质生产力”是一个相对较新的概念&#xff0c;指的是在数字化、智能化背景下&#xff0c;依托新技术、新业态、新模式&#xff0c;提升生产力质量和效率的一种生产力形态。它强调的是技术和创新对生产力的提升作用&#xff0c;尤其是在人工智能、大数据、互联网等新兴技术的推…...

《LeetCode热题100》---<5.②普通数组篇五道>

本篇博客讲解LeetCode热题100道普通数组篇中的六道题 第三道&#xff1a;轮转数组&#xff08;中等&#xff09; 第四道&#xff1a;除自身以外数组的乘积&#xff08;中等&#xff09; 第三道&#xff1a;轮转数组&#xff08;中等&#xff09; 方法一&#xff1a;使用额外的数…...

【面试题】【C语言】寻找两个正序数组的中位数

寻找两个正序数组的中位数 仅供学习 题目 算法时间复杂度 二分查找算法&#xff0c;时间复杂度为 O(log(min(m, n)))&#xff0c;其中 m 和 n 分别是两个数组的长度。 子函数 查找两个数字的最大值 int max(int a, int b) {return a > b ? a : b; }查找两个数字的最小…...

原始的原型链是怎样玩的

带着问题看代码&#xff1a; 1、原始的继承是怎样实现继承的&#xff1f; A类的prototype 属性 B类的实例 2、实现继承后&#xff0c;连B类的中实例的属性&#xff08;放在了A类的prototype中&#xff09;和原型链的上的东西都可以用 3、A.prototype.constructor实际上已经指向…...

RabbitMQ高级篇(如何保证消息的可靠性、如何确保业务的幂等性、延迟消息的概念、延迟消息的应用)

文章目录 1. 消息丢失的情况2. 生产者的可靠性2.1 生产者重连2.2 生产者确认2.3 生产者确认机制的代码实现2.4 如何看待和处理生产者的确认信息 3. 消息代理&#xff08;RabbitMQ&#xff09;的可靠性3.1 数据持久化3.2 LazyQueue&#xff08; 3.12 版本后所有队列都是 Lazy Qu…...

正点原子imx6ull-mini-Linux驱动之platform设备驱动实验(14)

我们在前面几章编写的设备驱动都非常的简单&#xff0c;都是对IO进行最简单的读写操作像I2C、 SPI、LCD 等这些复杂外设的驱动就不能这么去写了&#xff0c;Linux 系统要考虑到驱动的可重用性&#xff0c;因此提出了驱动的分离与分层这样的软件思路&#xff0c;在这个思路下诞生…...

z3基础学习

z3基础学习 ​ z3是一个微软出品的开源约束求解器&#xff0c;能够解决很多种情况下的给定部分约束条件寻求一组满足条件的解的问题。 安装&#xff1a;pip install z3-solver 1. 简单使用 from z3 import * x Int(x) #创建名为x的int类型变量 y Int(y) solve(x y10,2*x…...

开发助手专业版,有反编译等多种功能

软件介绍 开发助手能够用来快速调试应用以及查看手机软硬件相关信息&#xff0c;包括&#xff1a;快速打开或关闭开发者选项中的选项。 将原来几十秒的操作缩短为一次点击。包括显示布局边界&#xff0c;显示 GPU 过度绘制。显示布局更新。强制 GPU 渲染 显示 GPU 视图更新&a…...

嵌入式初学-C语言-十一

#接嵌入式初学-C语言-十,以及部分例题# 循环结构 break和continue break 功能&#xff1a; 1. 用在switch中&#xff0c;用来跳出switch的case语句&#xff1b;如果case没有break&#xff0c;可能会产生case穿透。 2. 用在循环中&#xff08;while、do..while、for..&#…...

浅谈几个常用OJ的注册方式

众所周知&#xff0c;好的OJ是成功的一半&#xff0c;但是有些英文OJ的注册很让人伤脑筋。 CodeForces 点进官网 戳这里 然后就会进入这个页面 在这一页里面里填写好信息即可 最后&#xff0c;一个邮件就会发到你的邮箱上&#xff0c;点击其中的链接即可激活账号 AtCoder …...

Html实现全国省市区三级联动

目录 前言 1.全国省市区的Json数据 2.找到Json数据文件(在此博文绑定资源)之后&#xff0c;放到resource目录下。 3.通过类加载器加载资源文件&#xff0c;读取Json文件 3.1 创建JsonLoader类 3.2 注入JsonLoader实体&#xff0c;解析Json文件 4.构建前端Html页面 5.通过…...

前端构建工具Webpack 与 Vite 大对比

在现代前端开发领域&#xff0c;构建工具扮演着至关重要的角色。它们不仅可以帮助我们管理项目依赖关系&#xff0c;还可以优化我们的代码&#xff0c;使其在生产环境中运行得更快更高效。其中两个最受欢迎的构建工具就是 Webpack 和 Vite。在这篇文章中&#xff0c;我们将深入…...

Ubuntu-22.04环境搭建

安装wget(一般ubuntu会自带) sudo apt-get install wget 更换国内软件源 先备份原来的/etc/apt/source.list⽂件 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 防止修改错误 导致无可挽回 将下列国内镜像源 写入原来的/etc/apt/source.list⽂件&#xff08;注…...

嵌入式学习---DAY17:共用体与位运算

链表剩余的一些内容 一、共用体 union 共用体名 名称首字母大写 { 成员表列&#xff1b; }&#xff1b; union Demo {int i;short s;char c; }; int main(void) {union Demo d;d.i 10;d.s 100;d.c 200;printf("%d\n", sizeof(d)); /…...

蓝牙网关和蓝牙MESH总结

可参考&#xff1a; https://zhuanlan.zhihu.com/p/695144946 蓝牙网关 参考&#xff1a; https://www.bilibili.com/read/cv28872282/ 蓝牙网关是一种特殊的网络设备&#xff0c;它能够实现蓝牙设备与互联网或其他类型网络之间的数据传输和通信。通过蓝牙网关&#xff0c;用户…...

了解关于标准化的知识

1.标准化组织 1.1国家标准化管理委员会(Standardization Administration of the Peoples Republic of China&#xff0c;简称SAC) TC--(Technical Committee) 技术委员会. SAC/TC,就是“国家标准化管理委员会”下属的一个专项或一个行业的“技术委员会或技术小组”&a…...

【云原生】数据库忘记密码怎么办?

相信很多人都会遇到在虚拟机中忘记数据库密码的情况&#xff0c;想必大家都很苦恼&#xff0c;所以今天给大家来讲讲数据库忘记密码了如何修改密码再登录数据库&#xff01;&#xff01;&#xff01; 1、关闭数据库服务 systemctl stop mariadb 2、执行MySQL 服务器在启动时跳…...

Postman 接口测试详解

Postman 接口测试详解 Postman 接口测试详解1. Postman 基础知识1.1 什么是 Postman&#xff1f;1.2 Postman 的主要功能 2. 安装与设置2.1 安装 Postman2.2 创建 Postman 账户 3. Postman 的基本操作3.1 创建和发送请求3.2 解析响应数据3.3 使用环境和变量 4. 进阶功能4.1 编写…...

【JavaEE】线程状态

目录 前言 一.线程状态图 二.线程状态 1.初始状态(NEW) 2.运行状态(RUNNING) 3.等待状态&#xff08;WAITING) 4.超时等待&#xff08;TIMED_WAITING) 5.阻塞状态&#xff08;BLOCKED) 6.终止状态(TERMINATED) 三.线程状态间的转换 四.总结 前言 线程状态及其状态转换…...

C++笔记之编译过程和面向对象

回顾&#xff1a; “abcd”//数据类型 字符串常量 const char *p"abc"; new STU const char *//8 指针的内存空间 int float 指针的内存空间 p 指针指向的内存空间 "abc" 取决于字符串长度 指针变量的内容一级指针 指针变量的地址二级指针 …...

ModuleNotFoundError: No module named ‘tqdm‘

报错信息&#xff1a; tqdm是一个快速、可扩展的Python进度条库&#xff0c;用于展示迭代器的长循环执行进度。 解决&#xff1a;通过以下命令安装 使用conda命令安装 conda install tqdm使用pip安装&#xff1a; pip install tqdm...

东京电影节公布2024年竞赛片评审团成员并对其业绩分别进行评介 没什么含金量

第37届东京国际电影节竞赛单元评审团名单正式公布。 周五&#xff0c;电影节组织者宣布&#xff0c;香港电影制片人杜琪峰、匈牙利电影制片人伊尔迪科恩耶迪、日本女演员桥本爱和法国女演员基娅拉马斯楚安尼将与之前宣布的评审团主席梁朝伟一起担任 2024 年主竞赛评审团成员。 …...

智能景区垃圾识别系统:基于YOLO的深度学习实现

基于深度学习的景区垃圾识别系统&#xff08;UI界面YOLOv8/v7/v6/v5代码训练数据集&#xff09; 1. 引言 景区垃圾识别是环保管理的重要任务之一。传统的人工清理方式效率低、成本高&#xff0c;而借助深度学习技术可以实现自动化的垃圾检测与识别&#xff0c;提高景区的清洁…...

ventoy和微pe可以共存吗?ventoy和pe共存使用教程

Ventoy新一代多系统启动U盘解决方案。国产开源U盘启动制作工具&#xff0c;支持Legacy BIOS和UEFI模式&#xff0c;理论上几乎支持任何ISO镜像文件&#xff0c;支持加载多个不同类型的ISO文件启动&#xff0c;无需反复地格式化U盘&#xff0c;插入U盘安装写入就能制作成可引导的…...

双语 网站 数据怎么做/vue seo 优化方案

写成宏&#xff0c;方便移植#define setbit(x,y) x|(1<//将X的第Y位置1#define clrbit(x,y) x&~(1<方法二:C语言位运算除了可以提高运算效率外&#xff0c;在嵌入式系统的编程中&#xff0c;它的另一个最典型的应用&#xff0c;而且十分广泛地正在被使用着的是位间的…...

wordpress产品筛选/阿里云注册域名

cat /etc/redhat-release...

如何选择邯郸网站制作/重庆seo排名公司

题目&#xff1a;题目描述连接 解答&#xff1a; select firstName,lastName,city,state from Person left join Address on Person.PersonId Address.PersonId;讲解&#xff1a; 多表连接 多表的联结又分为以下几种类型&#xff1a; 1&#xff09;左联结&#xff08;left …...

最专业的网站建设价格/看广告收益最高的软件

矩阵分析之 实矩阵分解&#xff08;1&#xff09;特征分解与奇异值分解前言特征分解&#xff08;又称谱分解、对角化&#xff09;奇异值分解SVDSVD的进一步理解前言 本篇开始学习记录矩阵分解内容。需要说明的是&#xff0c;目前我所触及的矩阵基本上没有出现复数域&#xff0…...

怎么通过做网站赚钱/seo搜索引擎优化关键词

L2-016. 愿天下有情人都是失散多年的兄妹 时间限制200 ms内存限制65536 kB代码长度限制8000 B判题程序Standard作者陈越呵呵。大家都知道五服以内不得通婚&#xff0c;即两个人最近的共同祖先如果在五代以内&#xff08;即本人、父母、祖父母、曾祖父母、高祖父母&#xff09;则…...

做mv主题网站/重庆百度seo公司

https://zhuanlan.zhihu.com/p/29150809 一、数据库有锁机制的原因。 数据库锁定机制简单来说&#xff0c;就是数据库为了保证数据的一致性和有效性&#xff0c;而使各种共享资源在被并发访问变得有序所设计的一种规则。对于任何一种数据库来说都需要有相应的锁定机制&#xff…...