实现Excel文件和其他文件导出为压缩包,并导入

导出

后端:

	@PostMapping("/exportExcelData")public void exportExcelData(HttpServletRequest request, HttpServletResponse response, @RequestBody ResData resData) throws IOException {List<Long> menuIds = resData.getMenuIds();List<Conversion> conversions = new ArrayList<>();List<String> ktrFilePaths = new ArrayList<>();for (Long menuId : menuIds) {Conversion conversion = conversionMapper.selectById(menuId);if (conversion != null) {conversions.add(conversion);String ktrFilePath = fileService.getKtrFilePathById(menuId);if (ktrFilePath != null && !ktrFilePaths.contains(ktrFilePath)) {ktrFilePaths.add(ktrFilePath);}}}// 创建Excel工作簿HSSFWorkbook workbook = new HSSFWorkbook();// 创建一个工作表Sheet sheet = workbook.createSheet("Conversions");// 创建单元格样式,并设置为文本格式CellStyle textStyle = workbook.createCellStyle();DataFormat format = workbook.createDataFormat();textStyle.setDataFormat(format.getFormat("@")); // "@" 表示文本格式// 创建标题行Row titleRow = sheet.createRow(0);// 创建单元格样式,并设置为文本格式titleRow.createCell(0).setCellValue("主键");titleRow.createCell(1).setCellValue("分组id");titleRow.createCell(2).setCellValue("名称");titleRow.createCell(3).setCellValue("备注");titleRow.createCell(4).setCellValue("创建人");titleRow.createCell(5).setCellValue("关联状态");titleRow.createCell(6).setCellValue("XMl");titleRow.createCell(7).setCellValue("创建时间");// 应用文本格式到标题行的特定单元格titleRow.getCell(0).setCellStyle(textStyle);titleRow.getCell(1).setCellStyle(textStyle);// 填充数据int rowNum = 1;for (Conversion conversion : conversions) {Row row = sheet.createRow(rowNum++);Cell cell = row.createCell(0);cell.setCellValue(String.valueOf(conversion.getId()));cell.setCellStyle(textStyle);cell = row.createCell(1);cell.setCellValue(String.valueOf(conversion.getGroupId()));cell.setCellStyle(textStyle); // 应用文本格式row.createCell(2).setCellValue(conversion.getName());row.createCell(3).setCellValue(conversion.getRemark());row.createCell(4).setCellValue(conversion.getCreateUserName());row.createCell(5).setCellValue(conversion.getState());row.createCell(6).setCellValue(conversion.getEditXml());row.createCell(7).setCellValue(String.valueOf(conversion.getCreateTime()));}// 设置响应头response.setContentType("application/vnd.ms-excel");response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("conversions.xls", "UTF-8"));// 设置响应头response.setContentType("application/zip");response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("conversions.zip", "UTF-8"));ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());// 将Excel文件添加到压缩包ZipEntry excelEntry = new ZipEntry("conversions.xls");zipOut.putNextEntry(excelEntry);workbook.write(zipOut);zipOut.closeEntry();workbook.close();// 添加.ktr文件到ktr目录for (String filePath : ktrFilePaths) {File ktrFile = new File(filePath);if (ktrFile.exists()) {FileInputStream fis = new FileInputStream(ktrFile);// 创建ZipEntry时,需要包含ktr目录ZipEntry ktrEntry = new ZipEntry("ktr/" + ktrFile.getName());zipOut.putNextEntry(ktrEntry);byte[] bytes = new byte[1024];int length;while ((length = fis.read(bytes)) >= 0) {zipOut.write(bytes, 0, length);}fis.close();zipOut.closeEntry();}}// 完成压缩包zipOut.finish();zipOut.close();}

导出后的文件组成:

excel文件:

前端:

<template><div class="app-container" style="width:100%;"><el-form label-width="80px" label-position="left"><el-form-item label="模型树"><el-treeref="tree":data="treeData"show-checkbox:default-expand-all="false"node-key="id"highlight-current:props="defaultProps"/></el-form-item></el-form><div style="text-align: center;width:100%;"><el-button type="primary" @click="onSave">导出</el-button><el-button type="danger" @click="closePage">取消</el-button></div></div>
</template><script>
import { getTreeData } from '@/api/dataSchema'
import { exportData,exportExcelData } from '@/api/conversion'
import { Message } from 'element-ui'export default {name: 'Zzjg',inject: ['getList'],props: {proid: {type: String,required: true}},data() {return {defaultProps: {children: 'children',label: 'name'},treeData: []}},methods: {getDetailed() {const loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})getTreeData().then(response => {this.treeData = response.dataloading.close()}).catch(function() {loading.close()})},onSave() {var menuIds = this.$refs.tree.getCheckedKeys()if (menuIds.length === 0) {Message({message: '请选择要导出的模型',type: 'error',duration: 5 * 1000})return} else {const loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})exportExcelData({ menuIds: menuIds }).then(response => {var fileName = 'download.zip'const contentDisposition = response.headers['content-disposition']if (contentDisposition) {fileName = window.decodeURI(response.headers['content-disposition'].split('=')[1], 'UTF-8')}const blob = new Blob([response.data], {type: `application/zip` // word文档为msword,pdf文档为pdf})const objectUrl = URL.createObjectURL(blob)const link = document.createElement('a')link.href = objectUrllink.setAttribute('download', fileName)document.body.appendChild(link)link.click()// 释放内存window.URL.revokeObjectURL(link.href)Message({message: '导出成功',type: 'success',duration: 5 * 1000})loading.close()this.$emit('update:visible', false)this.getList()}).catch(response => {loading.close()})}},closePage() {this.$emit('update:visible', false)this.getList()}}
}
</script>

代码拆解:

通过前端传来的menuIds进行遍历,把每一条数据插到excel里面并且通过menuIds找到文件名与之对应的ktr文件放到文件夹中。

for (Long menuId : menuIds) {Conversion conversion = conversionMapper.selectById(menuId);if (conversion != null) {conversions.add(conversion);String ktrFilePath = fileService.getKtrFilePathById(menuId);if (ktrFilePath != null && !ktrFilePaths.contains(ktrFilePath)) {ktrFilePaths.add(ktrFilePath);}}}

创建excel导出模板:

// 创建Excel工作簿HSSFWorkbook workbook = new HSSFWorkbook();// 创建一个工作表Sheet sheet = workbook.createSheet("Conversions");// 创建单元格样式,并设置为文本格式CellStyle textStyle = workbook.createCellStyle();DataFormat format = workbook.createDataFormat();textStyle.setDataFormat(format.getFormat("@")); // "@" 表示文本格式// 创建标题行Row titleRow = sheet.createRow(0);// 创建单元格样式,并设置为文本格式titleRow.createCell(0).setCellValue("主键");titleRow.createCell(1).setCellValue("分组id");titleRow.createCell(2).setCellValue("名称");titleRow.createCell(3).setCellValue("备注");titleRow.createCell(4).setCellValue("创建人");titleRow.createCell(5).setCellValue("关联状态");titleRow.createCell(6).setCellValue("XMl");titleRow.createCell(7).setCellValue("创建时间");// 应用文本格式到标题行的特定单元格titleRow.getCell(0).setCellStyle(textStyle);titleRow.getCell(1).setCellStyle(textStyle);// 填充数据int rowNum = 1;for (Conversion conversion : conversions) {Row row = sheet.createRow(rowNum++);Cell cell = row.createCell(0);cell.setCellValue(String.valueOf(conversion.getId()));cell.setCellStyle(textStyle);cell = row.createCell(1);cell.setCellValue(String.valueOf(conversion.getGroupId()));cell.setCellStyle(textStyle); // 应用文本格式row.createCell(2).setCellValue(conversion.getName());row.createCell(3).setCellValue(conversion.getRemark());row.createCell(4).setCellValue(conversion.getCreateUserName());row.createCell(5).setCellValue(conversion.getState());row.createCell(6).setCellValue(conversion.getEditXml());row.createCell(7).setCellValue(String.valueOf(conversion.getCreateTime()));}

我这里的id和groupId位数特别长,所以对这两列做了默认为文本的处理,否则会变成科学计数法,会丢精。

具体如下:
 

// 创建单元格样式,并设置为文本格式CellStyle textStyle = workbook.createCellStyle();DataFormat format = workbook.createDataFormat();textStyle.setDataFormat(format.getFormat("@")); // "@" 表示文本格式// 应用文本格式到标题行的特定单元格titleRow.getCell(0).setCellStyle(textStyle);titleRow.getCell(1).setCellStyle(textStyle);Row row = sheet.createRow(rowNum++);Cell cell = row.createCell(0);cell.setCellValue(String.valueOf(conversion.getId()));cell.setCellStyle(textStyle);cell = row.createCell(1);cell.setCellValue(String.valueOf(conversion.getGroupId()));cell.setCellStyle(textStyle); // 应用文本格式

把excel文件添加到压缩包:

	// 将Excel文件添加到压缩包ZipEntry excelEntry = new ZipEntry("conversions.xls");zipOut.putNextEntry(excelEntry);workbook.write(zipOut);zipOut.closeEntry();workbook.close();

把ktr文件放到ktr命名的文件夹中,并关闭压缩文件流

// 添加.ktr文件到ktr目录for (String filePath : ktrFilePaths) {File ktrFile = new File(filePath);if (ktrFile.exists()) {FileInputStream fis = new FileInputStream(ktrFile);// 创建ZipEntry时,需要包含ktr目录ZipEntry ktrEntry = new ZipEntry("ktr/" + ktrFile.getName());zipOut.putNextEntry(ktrEntry);byte[] bytes = new byte[1024];int length;while ((length = fis.read(bytes)) >= 0) {zipOut.write(bytes, 0, length);}fis.close();zipOut.closeEntry();}}// 完成压缩包zipOut.finish();zipOut.close();

导出就完成了。

导入

后端

导入的时候有一个要求,就是把导出时的id作为老的id存到数据库里,并生成新的id把新的id作为对应ktr的文件名存到对应的路径下面

解析数据:

	@PostMapping("/insertData")public ResultData insertData(@RequestAttribute Long _userId, HttpServletRequest request) {MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;MultipartFile uploadFile = req.getFile("uploadfile_ant");String originalName = uploadFile.getOriginalFilename();String docPath = "";List<Long> codes = new ArrayList<>(); // 用于存储所有导入的 IDtry {String classpath = ResourceUtils.getURL("classpath:").getPath();String path = classpath + File.separator + "static" + File.separator + "file" + File.separator + "yulan";docPath = path + File.separator + originalName;File dir = new File(path);if (!dir.exists()) {dir.mkdirs();}// 保存压缩文件File zipFile = new File(docPath);FileCopyUtils.copy(uploadFile.getInputStream(), new FileOutputStream(zipFile));// 解压压缩文件File unzipDir = new File(zipFile.getPath().substring(0, zipFile.getPath().lastIndexOf(".zip")));if (!unzipDir.exists()) {unzipDir.mkdirs();}unzipFile(zipFile, unzipDir);// 处理解压后的文件processUnzippedFiles(unzipDir);return ResultData.success("ok", codes); // 返回所有导入的 ID 列表} catch (Exception e) {e.printStackTrace();return ResultData.error("error");}}

解压代码:

private void unzipFile(File zipFile, File unzipDir) throws IOException {try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFile))) {ZipEntry entry = zipIn.getNextEntry();while (entry != null) {String filePath = unzipDir.getPath() + File.separator + entry.getName();if (!entry.isDirectory()) {extractFile(zipIn, filePath);} else {File dir = new File(filePath);dir.mkdirs();}zipIn.closeEntry();entry = zipIn.getNextEntry();}}}
	private void extractFile(ZipInputStream zipIn, String filePath) throws IOException {new File(filePath).getParentFile().mkdirs();try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) {byte[] bytesIn = new byte[4096];int read = 0;while ((read = zipIn.read(bytesIn)) != -1) {bos.write(bytesIn, 0, read);}}}

根据不同的文件类型去做不同的处理:

	private void processUnzippedFiles(File unzipDir) throws Exception {// 遍历解压后的目录,处理每个文件Files.walk(unzipDir.toPath()).forEach(filePath -> {try {if (Files.isRegularFile(filePath) && filePath.toString().endsWith(".xls")) {//如果是excel文件processExcelFile(filePath, unzipDir.toPath());
//						} else if (Files.isDirectory(filePath) && "ktr".equals(filePath.getFileName().toString())) {
//							//ktr文件夹
//							processKtrDirectory(filePath);}} catch (Exception e) {e.printStackTrace();}});}

处理excel:

@Transactionalpublic void processExcelFile(Path filePath, Path zipPath) throws Exception {Workbook workbook = null;try {FileInputStream excelFile = new FileInputStream(filePath.toFile());workbook = WorkbookFactory.create(excelFile); // 支持多种格式// 假设我们只处理第一个工作表Sheet sheet = workbook.getSheetAt(0);// 跳过标题行int startRowIndex = 1;DataFormatter formatter = new DataFormatter();for (int i = startRowIndex; i <= sheet.getLastRowNum(); i++) {Row row = sheet.getRow(i);if (row != null) {// 假设Excel文件的列顺序和数据库字段对应Cell idCell = row.getCell(0);Cell groupIdCell = row.getCell(1);Cell NameCell = row.getCell(2);Cell remarkCell = row.getCell(3);Cell creatorCell = row.getCell(4);Cell xmlCell = row.getCell(6);// 检查空值和数据转换String setOldId = formatter.formatCellValue(row.getCell(0));String groupId = formatter.formatCellValue(row.getCell(1));String remark = (remarkCell != null) ? remarkCell.getStringCellValue() : null;String Name = (NameCell != null) ? NameCell.getStringCellValue() : null;String creator = (creatorCell != null) ? creatorCell.getStringCellValue() :null;String state = formatter.formatCellValue(row.getCell(5));String XML = (xmlCell != null) ? xmlCell.getStringCellValue() : null;// 创建一个数据对象,例如DataObject,并填充字段Conversion conversion = new Conversion();conversion.setId(SnowflakeIdGenerator.getId());conversion.setOldId(Long.parseLong(setOldId));conversion.setGroupId(Long.parseLong(groupId));conversion.setName(Name);conversion.setRemark(remark);conversion.setCreateUserId(creator);conversion.setState(Integer.parseInt(state));conversion.setEditXml(XML);conversion.setCreateTime(LocalDateTime.now());// 保存到数据库conversionMapper.insert(conversion);//ktr文件夹processKtrDirectory(zipPath, conversion.getId(), conversion.getOldId());}}} catch (Exception e) {throw new Exception("Error processing Excel file", e);} finally {if (workbook != null) {try {workbook.close();} catch (IOException e) {// Log and handle workbook close exception}}}}

处理ktr:

private void processKtrDirectory(Path ktrDir, Long newId, Long oldId) throws Exception {// 处理ktr文件夹,将文件保存到磁盘路径下的逻辑// 例如:String targetPath = ktrPath + File.separator + Constant.kettleScriptFileName + File.separator + Constant.ktrFileName + File.separator;String newPath = ktrDir.toString()+"/ktr";try {Files.copy(Paths.get(newPath + File.separator + oldId.toString()), Paths.get(targetPath + newId.toString()));} catch (IOException e) {e.printStackTrace();}}

用copy(source,target)就可以实现把文件保存到指定路径

fileService.getKtrFilePathById:

/*** 根据menuId获取对应的.ktr文件路径。* @return 文件路径*/
@Service
@Transactional
public class FileServiceImpl implements FileService {@Value("${ktr.path}")private String ktrPath;public String getKtrFilePathById(Long menuId) {// 假设.ktr文件存储在 "/path/to/ktr/files/" 目录下,文件名为 "menuId.ktr"String baseDir = ktrPath + File.separator + Constant.kettleScriptFileName + File.separator + Constant.ktrFileName+File.separator;File file = new File(baseDir + menuId);if (file.exists()) {return file.getAbsolutePath();} else {return null; // 或者抛出一个异常,表示文件不存在}}
}

前端:

<template><div class="app-container" style="margin: 0 auto;width:100%;"><el-form ref="form" label-width="80px" label-position="left"><!-- <el-form-item><div slot="label">分组<font color="red">*</font></div><el-select v-model="form.groupId" placeholder="请选择分组" style="width: 100%"><el-option v-for="item in fzList" :key="item.id" :label="item.name" :value="item.id" /></el-select></el-form-item> --><!-- <el-form-item><div slot="label">模型名称<font color="red">*</font></div><el-input v-model="form.name" style="width:100%;" :autosize="{ minRows: 2, maxRows: 2}" /></el-form-item> --><el-form-item><div slot="label">导入模型<font color="red">*</font></div><el-uploadaccept=".zip"ref="upload"name="uploadfile_ant"class="upload-demo":limit="1":action="uploadpath":headers="uoloadheaders":before-upload="beforeAvatarUpload":on-success="handleAvatarSuccess":on-change="handleChange":on-remove="handleRemove":on-exceed="handleExceed":file-list="fileList"><el-button size="small" icon="el-icon-upload" type="primary">选择模型文件</el-button><span style="color:red;">  上传文件大小不能超过100MB</span></el-upload></el-form-item><!-- <el-form-item label="备注:"><el-input v-model="form.remark" type="textarea" maxlength="200" rows="6" placeholder="备注" /></el-form-item> --></el-form><!-- <div style="text-align: center;width:100%;"><el-button type="primary" @click="onSave">保存</el-button><el-button type="danger" @click="closePage">取消</el-button></div> --></div>
</template><script>
import { getWorkList } from '@/api/dataSchema'
import { updateData } from '@/api/conversion'import { Message, MessageBox } from 'element-ui'
import tool from '@/utils/tool'export default {name: 'Zzjg',inject: ['getList'],props: {proid: {type: String,required: true}},data() {return {uploadpath: '',uoloadheaders: {},fileData: '', // 文件上传数据(多文件合一)fileList: [], // upload多文件数组fzList: [],form: {},code: ''}},methods: {getDetailed() {getWorkList().then(response => {        this.fzList = response.datalet address = process.env.NODE_ENV == 'development' ? process.env.VUE_APP_URL_RECON : process.env.VUE_APP_BASE_API;var path = '/ltcloud/conversion/insertData'this.uploadpath = address + paththis.uoloadheaders = {'X-TOKEN' : tool.getCookie('X-Token'),'client-url':location.href,'applicationId':this.applicationId}})},handleAvatarSuccess(res, file) {if (res.code === 20000) {this.code = res.dataMessage({message: '上传成功',type: 'success',duration: 5 * 1000})} else {Message({message: res.msg,type: 'error',duration: 5 * 1000})}},// 移除handleRemove(file, fileList) {this.fileList = fileList},beforeAvatarUpload(file) {const isLt2M = file.size / 1024 / 1024 < 100if (!isLt2M) {this.$message.error('上传文件大小不能超过100MB!')}return isLt2M},// 选取文件超过数量提示handleExceed(files, fileList) {this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)},// 监控上传文件列表handleChange(file, fileList) {const existFile = fileList.slice(0, fileList.length - 1).find(f => f.name === file.name)if (existFile) {this.$message.error('当前文件已经存在!')fileList.pop()}this.fileList = fileList},onSave() {console.log('分组不能为空')if (!this.form.groupId) {this.$message.error('分组不能为空')return} else if (!this.form.name) {this.$message.error('模型名称不能为空')return} else if (this.fileList.length === 0) {this.$message.error('导入模型不能为空')return} else {const loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})this.form.idList = this.codeupdateData(this.form).then(response => {Message({message: '编辑成功',type: 'success',duration: 5 * 1000})loading.close()this.$emit('update:visible', false)this.getList()}).catch(response => {loading.close()this.getList()})}},closePage() {this.$emit('update:visible', false)this.getList()}}
}
</script><style lang="less">/deep/ .el-dialog {width: 550px;height: 650px;}.displayCol {display: flex;}.newNum {height: 20px;width: 20px;border: 1px solid #333;border-radius: 50%;text-align: center;margin-top: 3px;line-height: 20px;}/deep/.el-form-item__label {text-align: left !important;padding: 0 10px;}.disabled-text {pointer-events: none; /* 阻止鼠标事件 */cursor: default; /* 将鼠标光标设置为默认样式,表明文本不可点击 */opacity: 0.5; /* 降低文本的不透明度以显示出它是不可交互的 */user-select: none; /* 禁止文本被选中 */}.el-upload-list {float: left;margin: 0;padding: 0;list-style: none;}.el-upload {margin-left: 0px;display: inline-block;text-align: center;cursor: pointer;outline: 0;}.el-upload__tip {font-size: 12px;color: #606266;margin-top: 7px;width: 300px;line-height: 45px;height: 10px;}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/479300.html

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

相关文章

4.4 JMeter 请求参数类型详解

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 前言1 参数&#xff08;键值对形式&#xff09;2 消息体数据&#xff08;JSON/XML 格式&#xff09;3 文件上传 前言 在使用 JMeter 进行接口测试时&#xff0c;常见的请求参数类型主…

【山大909算法题】2014-T1

文章目录 1.原题2.算法思想3.关键代码4.完整代码5.运行结果 1.原题 为带表头的单链表类Chain编写一个成员函数Reverse&#xff0c;该函数对链表进行逆序操作&#xff08;将链表中的结点按与原序相反的顺序连接&#xff09;&#xff0c;要求逆序操作就地进行&#xff0c;不分配…

Apache OFBiz xmlrpc XXE漏洞(CVE-2018-8033)

目录 1、漏洞描述 2、EXP下载地址 3、EXP利用 1、漏洞描述 Apache OFBiz是一套企业资源计划&#xff08;ERP&#xff09;系统。它提供了广泛的功能&#xff0c;包括销售、采购、库存、财务、CRM等。 Apache OFBiz还具有灵活的架构和可扩展性&#xff0c;允许用户根据业务需求…

路由传参、搜索、多选框勾选、新增/编辑表单复用

前言&#xff1a; 记录添加运动员页面功能的具体实现 ①由赛事管理页面跳转时路由传参&#xff08;携带该页面表格中莫某条数据对应的赛事id到另一个页面&#xff09;&#xff1b; ②搜索框实时搜索&#xff1b; ③多选框勾选搜索&#xff1b; ④新增表单和编辑表单复用&a…

【11-20期】Java面试进阶:深入解析核心问题与实战案例

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Java &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 文章题目&#xff1a;Java面试进阶&#xff1a;深入解析11-20期核心问题与实战案例 摘要&#xff1a; 本篇…

Java后端如何进行文件上传和下载 —— 本地版

简介&#xff1a; 本文详细介绍了在Java后端进行文件上传和下载的实现方法&#xff0c;包括文件上传保存到本地的完整流程、文件下载的代码实现&#xff0c;以及如何处理文件预览、下载大小限制和运行失败的问题&#xff0c;并提供了完整的代码示例。 大体思路 1、文件上传 …

基于SpringBoot的工程教育认证的计算机课程管理系统【附源码】

基于SpringBoot的工程教育认证的计算机课程管理系统 效果如下&#xff1a; 系统登录页面 教师主页面 学生管理页面 课程信息页面 通知公告页面 学生课程管理页面 学生课程信息页面 研究背景 随着信息技术的快速发展&#xff0c;计算机课程管理系统的应用在教育领域变得愈发重…

适用于学校、医院等低压用电场所的智能安全配电装置

引言 电力&#xff0c;作为一种清洁且高效的能源&#xff0c;极大地促进了现代生活的便捷与舒适。然而&#xff0c;与此同时&#xff0c;因使用不当或维护缺失等问题&#xff0c;漏电、触电事件以及电气火灾频发&#xff0c;对人们的生命安全和财产安全构成了严重威胁&#xf…

如何编写一个 Vue 3 应用:模板插值示例

Vue.js 是一个渐进式的 JavaScript 框架&#xff0c;用于构建用户界面。在本篇博客中&#xff0c;我们将通过一个简单的示例来学习如何使用 Vue 3 创建一个基本的应用。这个示例将展示如何使用 Vue 的模板插值和事件处理来构建一个简单的点击计数器。 步骤 1: 准备工作 首先&…

PostgreSQL详细安装教程

#安装PostgreSQL的yum仓库 sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm#安装PostgreSQL 15版本 sudo yum install -y postgresql15-server#初始化数据库&#xff08;若要自定义数据库存储目录…

uniapp中使用Mescroll实现下拉刷新与上拉加载项目实战

如何在UniApp中使用Mescroll实现下拉刷新与上拉加载 前言 下拉刷新和上拉加载更多成为了提升用户体验不可或缺的功能。UniApp作为一个跨平台的应用开发框架&#xff0c;支持使用Vue.js语法编写多端&#xff08;iOS、Android、H5等&#xff09;应用。Mescroll作为一款专为Vue设…

js:基础

js是什么 JavaScript是一种运行在客户端的编程语言&#xff0c;实现人机交互的效果 js只要有个浏览器就能跑 js可以做网页特效、表单验证、数据交互、服务端编程 服务端编程是前端人拿他们特有的后端语言node.js来干后端干的事情 js怎么组成 JavaScriptECMAScript(语言基…

Cannot find a valid baseurl for repo: centos-sclo-rh/x86_64

yum install 报错: Cannot find a valid baseurl for repo: centos-sclo-rh/x86_64 CentOS7的SCL源在2024年6月30日停止维护了。 当scl源里面默认使用了centos官方的地址&#xff0c;无法连接&#xff0c;需要替换为阿里云。 cd /etc/yum.repos.d/ 找到 CentOS-SCLo-scl.repo 和…

35 基于单片机的精确电压表DA-AD转换

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DAC0832和ADC0832检测电压&#xff0c;0到8.5V&#xff0c;设计复位电路 LED管显示实际稳压值&#xff0c;初始电压0 二、硬件资源 基于KEIL5编写C代码&#xff0c…

微信小程序2-地图显示和地图标记

一、index修改页面&#xff0c;让页面能够显示地图和一个添加标记的按钮。 index.wxml <scroll-view class"scrollarea" scroll-y type"list"><view class"index_container"><map id"map" style"width: 100%; h…

【一篇搞定配置】网络分析工具WireShark的安装与入门使用

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;各种软件安装与配置_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1.…

Python基础学习-11函数参数

1、"值传递” 和“引用传递” 1&#xff09;不可变的参数通过“值传递”。比如整数、字符串等 2&#xff09;可变的参数通过“引用参数”。比如列表、字典。 3&#xff09;避免可变参数的修改 4&#xff09;内存模型简介 2、函数参数类型 1&#xff09; def func() #无参…

深入理解注意力机制(Attention Mechanism)

在深度学习中&#xff0c;“注意力机制&#xff08;Attention Mechanism&#xff09;”是近年来的一个重要突破。它最初被提出用于处理自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;但如今已经广泛应用于计算机视觉、强化学习和其他领域。注意力机制赋予模型一种“…

linux-FTP服务器配置

FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09; 一种用于在计算机网络中传输文件的标准协议。它允许用户通过客户端程序与远程服务器进行文件交换&#xff0c;支持文件的上传、下载、删除、重命名等操作。FTP服务常用于将网站文件上传到服务器&am…

蓝网科技临床浏览系统存在SQL注入漏洞

漏洞描述 蓝网科技临床浏览系统是一个专门用于医疗行业的软件系统&#xff0c;主要用于医生、护士和其他医疗专业人员在临床工作中进行信息浏览、查询和管理。在deleteStudy.php中的接口处存在SQL注入漏洞&#xff0c;未经身份验证的恶意攻击者利用 SQL 注入漏洞获取数据库中的…