如何在数据库中存储上传Excel的文件名?求助(附代码)
解决Excel上传时同时存储文件名到数据库的问题
我看了你的代码,发现你目前是手动解析multipart请求内容,这种方式不仅容易出bug,也没用到你尝试的DiskFileItemFactory组件。咱们可以改用Apache Commons FileUpload组件来更优雅地处理文件上传,同时轻松获取文件名,再把它和Excel内容一起存入数据库。
关键修改思路
- 放弃手动解析multipart数据流的方式,用
DiskFileItemFactory和ServletFileUpload来处理上传请求,这是Apache官方推荐的标准方案 - 通过
FileItem对象直接获取上传文件的原始文件名,无需自己截取字符串(还能自动处理不同浏览器带路径的文件名问题) - 可以直接从
FileItem获取输入流处理Excel,不用先把文件保存到本地(如果需要本地备份也可以保留这一步) - 在数据库插入逻辑中,新增文件名的字段存储
修改后的完整upload.jsp代码
<%@page import="java.util.List"%> <%@page import="org.apache.commons.fileupload.FileItem"%> <%@page import="org.apache.commons.fileupload.FileItemFactory"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="java.sql.*" %> <%@page import ="java.util.Date" %> <%@page import ="java.io.*" %> <%@page import ="java.util.Iterator" %> <%@page import ="java.util.ArrayList" %> <%@page import="org.apache.poi.ss.usermodel.Cell" %> <%@page import ="org.apache.poi.ss.usermodel.Row"%> <%@page import="org.apache.poi.ss.usermodel.Sheet" %> <%@page import="org.apache.poi.ss.usermodel.Workbook" %> <%@page import="org.apache.poi.xssf.usermodel.XSSFWorkbook"%> <%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%> <%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <% try { // 初始化FileUpload组件 FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); // 设置上传文件的最大大小(可选,这里设为10MB) upload.setSizeMax(10 * 1024 * 1024); // 解析请求,获取所有上传项 List<FileItem> items = upload.parseRequest(request); Iterator<FileItem> iter = items.iterator(); while (iter.hasNext()) { FileItem item = iter.next(); // 判断当前项是否是文件(不是普通表单字段) if (!item.isFormField()) { // 获取上传文件的原始文件名,自动处理浏览器路径问题 String fileName = item.getName(); fileName = fileName.substring(fileName.lastIndexOf(File.separator) + 1); out.println("上传的文件名:" + fileName + "<br>"); // 连接数据库 Class.forName("oracle.jdbc.driver.OracleDriver"); Connection con = DriverManager.getConnection("jdbc:oracle:thin:@172.18.114.213:1831:godb","xe","se"); // 从FileItem获取Excel文件的输入流,无需保存到本地 InputStream excelStream = item.getInputStream(); Workbook workbook = new XSSFWorkbook(excelStream); Sheet firstSheet = workbook.getSheetAt(0); Iterator<Row> rowIterator = firstSheet.iterator(); // 跳过表头(如果你的Excel第一行是表头的话,可根据实际情况调整) if (rowIterator.hasNext()) { rowIterator.next(); } // 准备插入数据的SQL,新增filename字段(请替换成你的表名和字段) String sql = "INSERT INTO your_table (column1, column2, filename) VALUES (?, ?, ?)"; PreparedStatement psmnt = con.prepareStatement(sql); while (rowIterator.hasNext()) { Row nextRow = rowIterator.next(); Iterator<Cell> cellIterator = nextRow.cellIterator(); // 假设你的Excel有2列数据,对应数据库的column1和column2,可根据实际调整 int cellIndex = 1; while (cellIterator.hasNext()) { Cell cell = cellIterator.next(); // 根据单元格类型获取值,这里简单处理为字符串 String cellValue = ""; switch (cell.getCellType()) { case STRING: cellValue = cell.getStringCellValue(); break; case NUMERIC: cellValue = String.valueOf(cell.getNumericCellValue()); break; case BOOLEAN: cellValue = String.valueOf(cell.getBooleanCellValue()); break; default: cellValue = ""; } psmnt.setString(cellIndex++, cellValue); } // 设置文件名参数 psmnt.setString(cellIndex, fileName); // 执行插入 psmnt.executeUpdate(); } // 关闭资源,避免泄漏 psmnt.close(); con.close(); workbook.close(); excelStream.close(); out.println("文件上传及数据存储成功!"); } } } catch (Exception e) { e.printStackTrace(); out.println("上传失败:" + e.getMessage()); } %> </body> </html>
重要说明
- 依赖检查:确保你的项目中已经引入了
commons-fileupload.jar和commons-io.jar,这两个是Apache FileUpload组件的必要依赖。 - 表结构调整:你需要在你的数据库表中新增一个
filename字段(比如VARCHAR2(255)类型),用来存储上传的文件名。 - Excel适配:代码中假设Excel第一行是表头所以跳过了,同时处理了常见的单元格类型,你可以根据自己的Excel数据结构调整这部分逻辑。
- 资源管理:代码中已经处理了数据库连接、流等资源的关闭,避免资源泄漏。
这种方式比你之前手动解析multipart请求要可靠得多,而且能轻松获取到正确的文件名,同时完成Excel内容和文件名的数据库存储。
内容的提问来源于stack exchange,提问作者Atul
相关产品推荐
相关产品推荐

