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

【JavaWeb学习 | 第22篇】文件上传下载与 Excel 导入导出

【JavaWeb学习 | 第22篇】文件上传下载与 Excel 导入导出

恭喜你学到这里!前面我们已经掌握了Servlet + MVCFilterEL+JSTLAJAX+JSON等核心技术。今天这篇是 JavaWeb 开发中非常实用且高频的内容:文件上传与下载,以及企业开发中几乎必备的Excel 导入导出(使用 Apache POI)。

这两个功能直接关系到“用户能不能方便地传输文件”和“系统能不能高效地处理批量数据”。


一、文件上传(File Upload)

1. 前端表单要求(必须掌握)
<%-- upload.jsp --%> <form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data"> 选择文件:<input type="file" name="uploadFile" /><br><br> 描述:<input type="text" name="description" /><br><br> <input type="submit" value="上传" /> </form>

关键点enctype="multipart/form-data"(必须!否则后端无法接收文件)

2. 后端实现方式对比

推荐方式(2026年视角)

  • Servlet 3.0+ 原生方式@MultipartConfig+PartAPI):无需额外jar,简单。
  • Apache Commons FileUpload:功能更强大,支持大文件、进度条等(传统教程常用)。

我们以Commons FileUpload为例(兼容性好,学习价值高)。

所需jar包(放入 WEB-INF/lib):

  • commons-fileupload-1.5.jar
  • commons-io-2.16.1.jar(依赖)
3. UploadServlet 完整代码
// com.example.web.UploadServlet.java@WebServlet("/upload")@MultipartConfig(fileSizeThreshold=1024*1024*2,// 2MB 临时文件阈值maxFileSize=1024*1024*10,// 单个文件最大10MBmaxRequestSize=1024*1024*50// 整个请求最大50MB)publicclassUploadServletextendsHttpServlet{privatestaticfinalStringUPLOAD_DIR="uploads";// 相对路径@OverrideprotectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{// 获取上传目录的绝对路径(推荐放在 WEB-INF 外或自定义路径)StringuploadPath=getServletContext().getRealPath("")+File.separator+UPLOAD_DIR;FileuploadDir=newFile(uploadPath);if(!uploadDir.exists())uploadDir.mkdirs();try{// 使用 Commons FileUploadDiskFileItemFactoryfactory=newDiskFileItemFactory();ServletFileUploadupload=newServletFileUpload(factory);// 解析请求List<FileItem>items=upload.parseRequest(req);for(FileItemitem:items){if(!item.isFormField()){// 是文件StringfileName=newFile(item.getName()).getName();// 防止路径穿越StringfilePath=uploadPath+File.separator+fileName;// 保存文件item.write(newFile(filePath));req.setAttribute("message","文件上传成功!文件名:"+fileName);}else{// 是普通表单字段StringfieldName=item.getFieldName();Stringvalue=item.getString("UTF-8");System.out.println(fieldName+" = "+value);}}}catch(Exceptione){req.setAttribute("message","上传失败:"+e.getMessage());e.printStackTrace();}req.getRequestDispatcher("/upload.jsp").forward(req,resp);}}

安全建议

  • 文件名使用 UUID 重命名(防止覆盖和路径穿越)
  • 限制文件类型(图片/文档等)
  • 上传目录不要放在 Web 根目录下(防止直接访问)

二、文件下载(File Download)

1. DownloadServlet 代码
@WebServlet("/download")publicclassDownloadServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{StringfileName=req.getParameter("filename");// 如:测试文档.docx// 文件真实路径StringfilePath=getServletContext().getRealPath("")+"/uploads/"+fileName;Filefile=newFile(filePath);if(!file.exists()){resp.getWriter().write("文件不存在!");return;}// 设置响应头(关键!)resp.setContentType("application/octet-stream");resp.setContentLength((int)file.length());// 处理中文文件名乱码(通用方案)StringuserAgent=req.getHeader("User-Agent");StringencodedFileName;if(userAgent.contains("Firefox")){encodedFileName="=?utf-8?B?"+Base64.getEncoder().encodeToString(fileName.getBytes("utf-8"))+"?=";}else{encodedFileName=URLEncoder.encode(fileName,"UTF-8").replace("+","%20");}resp.setHeader("Content-Disposition","attachment; filename=\""+encodedFileName+"\"");// 流传输try(InputStreamin=newFileInputStream(file);OutputStreamout=resp.getOutputStream()){byte[]buffer=newbyte[4096];intbytesRead;while((bytesRead=in.read(buffer))!=-1){out.write(buffer,0,bytesRead);}out.flush();}}}

前端调用示例

<a href="${pageContext.request.contextPath}/download?filename=报告.docx">下载报告</a>

三、Excel 导入导出(Apache POI)

推荐使用 POI(目前最成熟):

  • .xls→ HSSF
  • .xlsx→ XSSF(推荐)

所需jar包(Maven 或直接下载):

  • poi-5.3.0.jar
  • poi-ooxml-5.3.0.jar
  • poi-ooxml-lite-5.3.0.jar
  • xmlbeans-5.2.1.jar等(根据版本配套)
1. Excel 导出(最常用)
// ExportExcelServlet.java@WebServlet("/exportExcel")publicclassExportExcelServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{// 模拟数据(实际从数据库查询)List<User>userList=UserService.findAll();// 创建工作簿XSSFWorkbookworkbook=newXSSFWorkbook();XSSFSheetsheet=workbook.createSheet("用户列表");// 创建标题行String[]headers={"ID","用户名","年龄","邮箱"};RowheaderRow=sheet.createRow(0);for(inti=0;i<headers.length;i++){Cellcell=headerRow.createCell(i);cell.setCellValue(headers[i]);}// 填充数据introwNum=1;for(Useruser:userList){Rowrow=sheet.createRow(rowNum++);row.createCell(0).setCellValue(user.getId());row.createCell(1).setCellValue(user.getUsername());row.createCell(2).setCellValue(user.getAge());row.createCell(3).setCellValue(user.getEmail());}// 设置响应头resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");StringfileName="用户列表_"+newSimpleDateFormat("yyyyMMdd").format(newDate())+".xlsx";StringencodedName=URLEncoder.encode(fileName,"UTF-8").replace("+","%20");resp.setHeader("Content-Disposition","attachment; filename=\""+encodedName+"\"");// 输出workbook.write(resp.getOutputStream());workbook.close();}}
2. Excel 导入(读取上传的Excel)

结合文件上传,先上传.xlsx,然后在 Servlet 中解析:

// 在上传成功后或单独的 ImportServlet 中XSSFWorkbookworkbook=newXSSFWorkbook(newFileInputStream(excelFile));XSSFSheetsheet=workbook.getSheetAt(0);for(inti=1;i<=sheet.getLastRowNum();i++){// 从第2行开始(跳过标题)Rowrow=sheet.getRow(i);Stringusername=row.getCell(0).getStringCellValue();intage=(int)row.getCell(1).getNumericCellValue();// ... 保存到数据库}workbook.close();

四、实际开发注意事项与最佳实践

  1. 文件上传安全

    • 校验文件类型(白名单:jpg/png/xlsx 等)
    • 重命名文件(UUID + 后缀)
    • 大小限制 + 病毒扫描(生产环境)
    • 上传目录定期清理或使用云存储(OSS)
  2. 下载中文文件名:必须处理 User-Agent,不同浏览器差异大,上面代码已给出通用方案。

  3. POI 性能

    • 大数据量导出推荐SXSSFWorkbook(流式写入,节省内存)
    • 导入时注意空行、空单元格处理
  4. 结合 AJAX:上传可以用 FormData + AJAX 实现无刷新上传 + 进度条。

  5. 推荐工具类:实际项目中会把导出/导入封装成工具类(ExcelUtil),便于复用。


五、练习建议(强烈推荐动手完成)

  1. 实现单文件上传 + 下载(支持图片和文档)。
  2. 实现用户列表 Excel 导出功能(包含日期格式化)。
  3. 实现 Excel 导入用户数据(读取后存入数据库或List)。
  4. 进阶:支持多文件上传 + 上传进度显示(结合 AJAX)。
  5. 挑战:实现带模板的 Excel 导出(使用 POI 或 jxls)。

完成这些后,你已经具备了开发“后台管理系统”中核心 CRUD + 文件操作的能力!


系列文章导航(持续更新中):

  • 第20篇:EL表达式与JSTL标签
  • 第21篇:AJAX与JSON详解
  • 第22篇:文件上传下载与 Excel 导入导出(本文)
  • 第23篇:Listener监听器(在线人数统计、Session监听、应用启动/销毁监听等)

下一篇文章预告:我们将学习Listener(监听器),它能监听应用、会话、请求的生命周期,是实现“在线人数统计”、“网站访问量统计”、“Session超时处理”等功能的必备技术。

有任何疑问(比如想看完整多文件上传代码、POI设置样式、或 SXSSFWorkbook 大数据导出示例),欢迎在评论区留言,我会及时补充更多细节和完整 Demo!

继续加油!掌握文件操作和 Excel 处理后,你的 JavaWeb 项目实用性将大幅提升,已经非常接近能独立完成中小型企业级 Web 应用了!💪

下一篇文章见~ 🚀

http://www.jsqmd.com/news/570877/

相关文章:

  • 调查财产线索哪家专业,连云港地区有靠谱的吗 - 工业推荐榜
  • 如何高效使用猫抓cat-catch:5个关键技巧完全指南
  • Windows系统性能优化全景指南:从问题诊断到持续优化
  • postman接口自动化如何进行参数化
  • 嵌入式设备OTA升级,如何用RSA-3072和Ed25519给固件‘验明正身’?
  • 轻量级投资决策中枢:TrafficMonitor股票插件的创新实践
  • 巴旦木脱青皮的设计【solidworks三维、cad图纸、论文、答辩稿】
  • 说说连云港强制执行律师费用,多少钱才合理? - myqiye
  • 如何快速掌握Vitest:让前端测试效率提升10倍的终极指南
  • 群晖7.X系统下SSH双重验证(OTP)的故障排查与关闭指南
  • 360误杀Go程序?教你设置专属安全编译目录(附各杀毒软件信任区设置图解)
  • 5分钟掌握:如何用这款免费工具让Windows飞起来?
  • 【完整源码+数据集+部署教程】儿童与成人目标检测系统源码分享[一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]
  • HSTracker:macOS炉石传说智能追踪器的终极指南
  • Vanilla论坛布局系统详解:灵活定制你的社区页面结构
  • 从零到一:NS2网络模拟器实战部署与场景构建指南
  • 『NAS』99 款 PDF 工具一站式搞定-PDFCraft
  • 题解:学而思编程 约瑟夫游戏
  • Pycharm集成gprMax 3.0:从环境配置到A/B扫描仿真的完整工作流
  • Zotero Actions Tags:自动化文献管理,告别手动标签整理
  • 模型调用总闸门再次被投毒
  • AMD Ryzen SDT调试工具:突破性实战指南,让你的处理器性能飙升200%
  • 技术解析:Planck-Pi如何重新定义嵌入式开发入门门槛
  • ER-Save-Editor技术架构解析:Rust实现的艾尔登法环存档编辑器深度剖析
  • Unity游戏Mod加载技术揭秘:MelonLoader双运行时架构深度解析
  • Matlab_Simulink与Carsim的联合仿 擅长基于群智能算法优化的LQR、PID控制算法,能清晰讲解其中要点哦。对于基于群智能算法的一般路径规划
  • Pock完全指南:免费开源的MacBook Touch Bar小部件管理器终极教程
  • 射频电路设计新手必看:ADS2017版图字体调整与Move Edge操作技巧
  • StructBERT文本相似度模型在Keil5开发环境中的调试与部署
  • 美胸-年美-造相Z-Turbo部署教程:解决Gradio跨域访问限制与HTTPS反向代理配置