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

news2024/11/27 6:56:18

导出

后端:

	@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-tree
          ref="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.data
        
        loading.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 = objectUrl
          link.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<>(); // 用于存储所有导入的 ID
		try {
			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:

@Transactional
	public 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-upload
          accept=".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.data

        let 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 + path
        
        this.uoloadheaders = {
          'X-TOKEN' : tool.getCookie('X-Token'),
          'client-url':location.href,
          'applicationId':this.applicationId
        }
      })
    },
    handleAvatarSuccess(res, file) {
      if (res.code === 20000) {
        this.code = res.data
        Message({
          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 < 100

      if (!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.code
        updateData(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.coloradmin.cn/o/2248265.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

某车企ASW面试笔试题

01--背景 去年由于工作岗位的动荡&#xff0c;于是面试了一家知名车企&#xff0c;上来进行了一番简单的介绍之后&#xff0c;被告知需要进入笔试环节&#xff0c;以往单位面试都是简单聊聊技术问题&#xff0c;比如对软件开发的流程或者使用的工具等待问题的交流&#xff0c;…

计算(a+b)/c的值

计算&#xff08;ab&#xff09;/c的值 C语言代码C语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 给定3个整数a、b、c&#xff0c;计算表达式(ab)/c的值&#xff0c;/是整除运算。 输入 输入仅一行&…

【在Linux世界中追寻伟大的One Piece】多线程(二)

目录 1 -> 分离线程 2 -> Linux线程互斥 2.1 -> 进程线程间的互斥相关背景概念 2.2 -> 互斥量mutex 2.3 -> 互斥量的接口 2.4 -> 互斥量实现原理探究 3 -> 可重入VS线程安全 3.1 -> 概念 3.2 -> 常见的线程不安全的情况 3.3 -> 常见的…

【NLP高频面题 - 分布式训练】ZeRO1、ZeRO2、ZeRO3分别做了哪些优化?

【NLP高频面题 - 分布式训练】ZeRO1、ZeRO2、ZeRO3分别做了哪些优化&#xff1f; 重要性&#xff1a;★★ NLP Github 项目&#xff1a; NLP 项目实践&#xff1a;fasterai/nlp-project-practice 介绍&#xff1a;该仓库围绕着 NLP 任务模型的设计、训练、优化、部署和应用&am…

AIGC--AIGC与人机协作:新的创作模式

AIGC与人机协作&#xff1a;新的创作模式 引言 人工智能生成内容&#xff08;AIGC&#xff09;正在以惊人的速度渗透到创作的各个领域。从生成文本、音乐、到图像和视频&#xff0c;AIGC使得创作过程变得更加快捷和高效。然而&#xff0c;AIGC并非完全取代了人类的创作角色&am…

C++11特性(详解)

目录 1.C11简介 2.列表初始化 3.声明 1.auto 2.decltype 3.nullptr 4.范围for循环 5.智能指针 6.STL的一些变化 7.右值引用和移动语义 1.左值引用和右值引用 2.左值引用和右值引用的比较 3.右值引用的使用场景和意义 4.右值引用引用左值及其一些更深入的使用场景分…

React中事件处理和合成事件:理解与使用

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

大数据新视界 -- 大数据大厂之 Hive 数据桶:优化聚合查询的有效手段(下)(10/ 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

基于FPGA的信号DM编解码实现,包含testbench和matlab对比仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 1.编码器硬件结构 2.解码器硬件结构 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) FPGA测试结果如下&#xff1a; matlab对比仿真结果如下&#xff1a; 2.算法运行软…

鸿蒙中拍照上传与本地图片上传

1.首页ui import { picker } from kit.CoreFileKit; import fs from ohos.file.fs; import request from ohos.request; import { promptAction } from kit.ArkUI; import { cameraCapture } from ./utils/CameraUtils; import { common } from kit.AbilityKit; import { Imag…

【算法】连通块问题(C/C++)

目录 连通块问题 解决思路 步骤&#xff1a; 初始化&#xff1a; DFS函数&#xff1a; 复杂度分析 代码实现&#xff08;C&#xff09; 题目链接&#xff1a;2060. 奶牛选美 - AcWing题库 解题思路&#xff1a; AC代码&#xff1a; 题目链接&#xff1a;687. 扫雷 -…

人工智能 实验2 jupyter notebook平台 打印出分类器的正确率

实验2 jupyter notebook平台 【实验目的】掌握jupyter notebook平台的使用方法 【实验内容】上传文件到jupyter notebook平台&#xff0c;学会编辑运行ipynb文件 【实验要求】写明实验步骤&#xff0c;必要时补充截图 安装Anaconda。 2、 将BreadCancer.zip上传到jupyter no…

【贪心算法第五弹——300.最长递增子序列】

目录 1.题目解析 题目来源 测试用例 2.算法原理 3.实战代码 代码解析 注意本题还有一种动态规划的解决方法&#xff0c;贪心的方法就是从动态规划的方法总结而来&#xff0c;各位可以移步博主的另一篇博客先了解一下&#xff1a;动态规划-子序列问题——300.长递增子序列…

Spring Boot——统一功能处理

1. 拦截器 拦截器主要用来拦截用户的请求&#xff0c;在指定方法前后&#xff0c;根据业务需要执行设定好的代码&#xff0c;也就是提前定义一些逻辑&#xff0c;在用户的请求响应前后执行&#xff0c;也可以在用户请求前阻止其执行&#xff0c;例如登录操作&#xff0c;只有登…

【2024】前端学习笔记19-ref和reactive使用

学习笔记 1.ref2.reactive3.总结 1.ref ref是 Vue 3 中用来创建响应式引用的一个函数&#xff0c;通常用于基本数据类型&#xff08;如字符串、数字、布尔值等&#xff09;或对象/数组的单一值。 ref特点&#xff1a; ref 可以用来创建单个响应式对象对于 ref 包裹的值&…

javaweb-day01-html和css初识

html:超文本标记语言 CSS&#xff1a;层叠样式表 1.html实现新浪新闻页面 1.1 标题排版 效果图&#xff1a; 1.2 标题颜色样式 1.3 标签内颜色样式 1.4设置超链接 1.5 正文排版 1.6 页面布局–盒子 &#xff08;1&#xff09;盒子模型 &#xff08;2&#xff09;页面布局…

3mf 格式详解,javascript加载导出3mf文件示例

3MF 格式详解 3MF&#xff08;3D Manufacturing Format&#xff09;是一种开放标准的文件格式&#xff0c;专门用于三维制造和打印。3MF 格式旨在解决 STL 格式的局限性&#xff0c;提供更丰富和灵活的数据表示。3MF 文件是一种 ZIP 文件&#xff0c;其中包含了描述三维模型的…

音视频流媒体直播/点播系统EasyDSS互联网视频云平台介绍

随着互联网技术的飞速发展&#xff0c;音视频流媒体直播已成为现代社会信息传递与娱乐消费的重要组成部分。在这样的背景下&#xff0c;EasyDSS互联网视频云平台应运而生&#xff0c;它以高效、稳定、便捷的特性&#xff0c;为音视频流媒体直播领域带来了全新的解决方案。 1、产…

c++:面向对象三大特性--继承

面向对象三大特性--继承 一、继承的概念及定义&#xff08;一&#xff09;概念&#xff08;二&#xff09;继承格式1、继承方式2、格式写法3、派生类继承后访问方式的变化 &#xff08;三&#xff09;普通类继承&#xff08;四&#xff09;类模板继承 二、基类和派生类的转换&a…

【Linux学习】【Ubuntu入门】2-5 shell脚本入门

1.shell脚本就是将连续执行的命令携程一个文件 2.第一个shell脚本写法 shell脚本是个纯文本文件&#xff0c;命令从上而下&#xff0c;一行一行开始执行&#xff0c;其扩展名为.sh&#xff0c;shell脚本第一行一定要为&#xff1a;#!/bin/bash&#xff0c;表示使用bash。echo…