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

【Java + Vue 实现图片上传后 导出图片及Excel 并压缩为zip压缩包】

系统环境:

Java JDK:1.8.0_202
Node.js:v12.2.0
Npm:6.9.0

Java后端实现

Controller

	/*** xxxx-导出* @param response 返回信息体* @param files 上传的图片文件* @param param1 参数1* @param param2 参数2*/@PostMapping("/exportXX")@ApiOperationSupport(order = 13)@ApiOperation(value = "导出Excel", notes = "导出Excel")@ApiLog("XXX导出")public void exportXX(HttpServletResponse response, @RequestParam("files") MultipartFile[] files, @RequestParam("param1") String param1,@RequestParam(value = "param2",defaultValue = "1") String param2) {tableExportService.exportXX(response, files, param1, param2);}

Service

	/*** XXX-导出*/void exportXX(HttpServletResponse response, MultipartFile[] files, String param1,String param2);

Impl

	/*** xxxx-导出* @param response 返回信息体* @param files  上传的图片文件* @param param1 参数1* @param param2 参数2*/@Overridepublic void exportXX(HttpServletResponse response,MultipartFile[] files,  String param1, String param2) {try {// 返回信息体重置response.reset();// 设置类型response.setContentType("application/force-download");// 赋值压缩包名称及头部信息SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String fileName = "attachment;filename=cryExcel" + format.format(new Date()) + ".zip";response.setHeader("Content-Disposition", fileName);// 发送二进制数据到客户端的输出流ServletOutputStream servletOutputStream = response.getOutputStream();ZipOutputStream zipOut = new ZipOutputStream(servletOutputStream);// 图片添加到ZIPaddPicToZip(files,zipOut);// 表头List<List<String>> headList = new ArrayList<>();// 固定列headList.add(Arrays.asList("列1"));headList.add(Arrays.asList("列名2"));headList.add(Arrays.asList("这是列名3"));// 导出数据List<List<String>> dataList = new ArrayList<>();// 自行获取需要导出为excel的数据信息List<Map<String, Object>> list = ……;// 列表不为空时按照列1进行排序if(Func.isNotEmpty(list)){list.sort(Comparator.comparing(map -> (String) map.get("列1的键")));}// 转换数据格式为二维数组 方便存入excelfor (Map<String, Object> item : list) {dataList.add(Arrays.asList(String.valueOf(item.getOrDefault("列1的值", "")),String.valueOf(item.getOrDefault("列2的值", "")),String.valueOf(item.getOrDefault("列3的值", "")) + "%"));}// 导出excel 并合并第一列的相同内容int[] mergeColumeIndex = {0};int mergeRowIndex = 1;String excelName = "导出excel.xlsx";File excelfile = new File(excelName);if (!excelfile.exists()) {excelfile.createNewFile();}// 将excel写入压缩包EasyExcel.write(excelName).head(headList).registerWriteHandler(new ExcelFillCellLineMergeHandler(mergeRowIndex, mergeColumeIndex)).sheet("导出excel").doWrite(dataList);// 创建 ZipEntryZipEntry entry = new ZipEntry(excelName);zipOut.putNextEntry(entry);// 读取文件并写入 ZipOutputStreamtry (FileInputStream fis = new FileInputStream(excelfile)) {byte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) > 0) {zipOut.write(buffer, 0, length);}}// 关闭当前的 ZipEntryzipOut.closeEntry();// 关流zipOut.close();} catch (Exception e){e.printStackTrace();}}/*** 将Base64编码的图片文件添加到ZIP输出流中* @param files 包含Base64编码的图片的MultipartFile数组* @param zipOut 目标ZIP输出流*/
private void addPicToZip(MultipartFile[] files, ZipOutputStream zipOut) {try {// 检查文件数组是否为空if (files != null) {// 遍历所有文件for (MultipartFile file : files) {// 从MultipartFile中获取输入流并转换为字符串String imageData = StreamUtils.copyToString(file.getInputStream(), StandardCharsets.UTF_8);// 移除Base64数据前缀(如果存在)imageData = imageData.replace("data:image/png;base64,", "");// 解码Base64字符串为字节数组byte[] imageBytes = Base64.getDecoder().decode(imageData);// 创建ZIP条目,使用原始文件名并添加.png扩展名ZipEntry zipEntry = new ZipEntry(file.getOriginalFilename() + ".png");// 将条目添加到ZIP输出流zipOut.putNextEntry(zipEntry);// 写入图片字节数据到ZIP条目zipOut.write(imageBytes, 0, imageBytes.length);}}} catch (IOException e) {// 打印异常堆栈信息e.printStackTrace();}
}
  • 注:对于此处我个人觉得直接让前端上传file二进制文件更好,后端直接获取file的字节码,然后弄进压缩包,此处可以根据业务需求自行调整~

Vue 前端实现

Api

/*** @description 测试导出* */
export const exportXX = (data) => {return request({headers: {"Content-Type": "multipart/form-data"// 指定请求体为多部分表单数据(用于文件上传)},method: 'post',responseType: 'blob',// 指定响应类型为二进制大对象(用于接收文件流)data,url: 'http://localhost:8990/dev-api/tableExport/exportXX',})
}

Vue

此处可以自行选择upload组件上传的文件或者echarts图形截图等文件进行上传

    // 上传图片信息async uploadImages() {try {// 创建FormDataconst formData = new FormData();if (this.selectedFiles.length !== 0) {// 处理每个文件for (const file of this.selectedFiles) {// 转换为完整的Base64 DataURL(包含前缀)const base64DataUrl = await this.convertToBase64(file);// 创建一个Blob对象,内容为Base64字符串(作为文本)const blob = new Blob([base64DataUrl], { type: "text/plain" });// 使用原始文件名创建File对象const fileToUpload = new File([blob], file.name, {type: "text/plain",});// 添加到FormDataformData.append("files", fileToUpload);}}formData.append("param1", "111");formData.append("param2", "222");// 调用导出接口await exportXX(formData).then((res) => {console.log(formData);console.log(res);if(res){const elink = document.createElement('a');elink.download = '文件名称.zip';elink.style.display = 'none';const blob = new Blob([res], { type: 'application/x-msdownload' });elink.href = URL.createObjectURL(blob);document.body.appendChild(elink);elink.click();document.body.removeChild(elink);}else {this.$message.error('导出异常请联系管理员');}});console.log("上传成功");} catch (error) {console.error("上传错误:", error);}},//转换为base64字符convertToBase64(file) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => resolve(reader.result); // 返回完整的DataURL(含前缀)reader.onerror = reject;reader.readAsDataURL(file);});},
http://www.xdnf.cn/news/15908.html

相关文章:

  • 【跨国数仓迁移最佳实践2】MaxCompute SQL执行引擎对复杂类型处理全面重构,保障客户从BigQuery平滑迁移
  • IDEA 同时修改某个区域内所有相同变量名
  • 深入解析IP协议:组成、地址管理与路由选择
  • Freemarker实现下载word可能遇到的问题
  • docker--挂载
  • 深入解析:如何在Kafka中配置Source和Sink连接器构建高效数据管道
  • 【Linux指南】Linux系统 -权限全面解析
  • 万界星空科技锂电池MES解决方案
  • 移星科技 modbus-tcp 转 modbus-Rtu模块
  • CMakeLists.txt 中一些最常见和核心的命令
  • AG32 cpld部分bin的烧录
  • 20250721
  • .NET依赖注入IOC你了解吗?
  • 14.6 《3步实战LLaMA2-7B指令微调:Hugging Face生态+LoRA技术,MT-Bench得分从5.1直升7.3》
  • 基于爬虫技术的电影数据可视化系统 Python+Django+Vue.js
  • C# 集合(Collection)
  • Playwright-MCP浏览器会话复用全解析
  • 企业管理效能提升之道——固定资产管理的价值体现
  • Flutter和Kotlin的对比
  • 北京-4年功能测试2年空窗-报培训班学测开-第五十六天
  • 【Docker#3】Window 和 Linux 上 docker安装 相关知识
  • 算法训练营day25 回溯算法④ 补充联系题目 332.重新安排行程、51. N皇后、37. 解数独
  • 【详细笔记】两类曲线积分转换
  • 14.多播与广播
  • ESMFold 安装教程
  • Linux主机 ->多机器登录
  • 尚庭公寓--------登陆流程介绍以及功能代码
  • PostgreSQL 字段类型速查与 Java 枚举映射
  • XSS的介绍
  • LWJGL教程(3)——时间