javaWeb项目开发文件上传与下载功能实现

发布时间 2023-12-13 15:27:44作者: Xproer-松鼠

Web开发文件上传与下载
依赖
<!--java生成excel文件插件-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>

文件下载
思路总结(将数据库数据保存到excel文件中并下载到本地):

从数据库中查询需要下载的数据
指定位置创建一个excel文件
借助第三方插件org.apache.poi
将数据写入创建的excel文件中
点击功能按钮下载数据,弹出下载窗口进行下载
步骤
设置响应头激活下载弹窗
创建Excel文件对象
在Excel文件对象中创建指定的页
在页中创建行和列进行数据的写入
获取响应的输出流,将Excel文件写入到本地磁盘
代码
前端(jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// 设置动态初始访问路径(这里本地是http://127.0.0.1:8080/crm/)
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<title>测试文件下载</title>
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>

<script type="text/javascript">
$(function () {
$("#filedownload").click(function () {
//发送文件下载请求(按理说是异步请求,但是所有文件下载的请求只能是同步请求!!)
window.location.href="workbench/activity/fileDownload"
})
})
</script>
</head>
<body>
<input type="button" value="下载" id="filedownload">
</body>
</html>


Cotroller层
public static void fileAllDownload(HttpServletResponse response,List<Activity> list) throws IOException {
//设置响应类型并激活下载弹窗
response.setContentType("application/octet-stream;charset=UTF-8");
response.addHeader("Content-Disposition","attachment;filename=my_activity.xls");

//创建excel文件对象
HSSFWorkbook workbook = new HSSFWorkbook();

//创建一页
HSSFSheet sheet = workbook.createSheet("市场活动表");
//设置表头
HSSFRow row = null;
row = sheet.createRow(0);
HSSFCell cell = null;
cell = row.createCell(0);
cell.setCellValue("id");

cell = row.createCell(1);
cell.setCellValue("所选者");

cell = row.createCell(2);
cell.setCellValue("活动名称");

cell = row.createCell(3);
cell.setCellValue("开始日期");

cell = row.createCell(4);
cell.setCellValue("结束日期");

cell = row.createCell(5);
cell.setCellValue("成本");

cell = row.createCell(6);
cell.setCellValue("描述");

cell = row.createCell(7);
cell.setCellValue("活动创建者");

cell = row.createCell(8);
cell.setCellValue("活动创建时间");

cell = row.createCell(9);
cell.setCellValue("活动修改时间");

cell = row.createCell(10);
cell.setCellValue("活动修改者");

//给文件写入数据
if (list!=null){
for (int i = 0; i < list.size(); i++) {
Activity activity = list.get(i);

row = sheet.createRow(i+1);
cell = row.createCell(0);
cell.setCellValue(activity.getId());
cell = row.createCell(1);
cell.setCellValue(activity.getOwner());
cell = row.createCell(2);
cell.setCellValue(activity.getName());
cell = row.createCell(3);
cell.setCellValue(activity.getStartDate());
cell = row.createCell(4);
cell.setCellValue(activity.getEndDate());
cell = row.createCell(5);
cell.setCellValue(activity.getCost());
cell = row.createCell(6);
cell.setCellValue(activity.getDescription());
cell = row.createCell(7);
cell.setCellValue(activity.getCreateBy());
cell = row.createCell(8);
cell.setCellValue(activity.getCreateTime());
cell = row.createCell(9);
cell.setCellValue(activity.getEditTime());
cell = row.createCell(10);
cell.setCellValue(activity.getEditBy());
}
}


//磁盘创建并生成excel文件
FileOutputStream fileOutputStream = new FileOutputStream("E:\\java\\CRM\\activity.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();
workbook.close();

//创建输出流(方便写文件到本地)
OutputStream outputStream = response.getOutputStream();
//创建输入流(读文件)!!!这种方式下载到本地的文件打开有错误!!!
// FileInputStream fileInputStream = new FileInputStream("E:\\java\\CRM\\activity.xls");
//这里表示读取服务端文件
// byte[] bytes = new byte[1024];
// int length = 0;
// while ((length=(fileInputStream.read()))!=-1){
// outputStream.write(bytes,0,length);
// }
workbook.write(outputStream);

// fileInputStream.close();
outputStream.flush();
}


文件上传
主要思路:

把文件上传至服务器
java解析上传到服务器的excel文件数据
把解析的数据封装成对应的实体类对象
执行sql语句将数据插入数据库
步骤
前端:创建form表单(主要form表单的enctype属性值设置为multipart/form-data)

enctype属性:就是用来设置通过form表单上传服务器的数据以哪种编码方式编码
multipart/form-data:支持向服务器发送二进制数据
点击“上传”按钮,跳转到Controller层执行指定的处理方法

处理方法通过MultipartFile工具类接收文件,并将文件写到服务器(对应在一台电脑开发而言只需要写到本地电脑即可)

MultipartFile:是SpringMVC封装的文件上传下载的工具类,使用时直接声明即可,不需要手动实例化

由于是SpringMVC框架给我们封装的,因此在配置文件中需要进行简单配置

<!--配置文件上传解析器-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<property name="maxUploadSize" value="#{1024*1024*8}"></property>
<property name="defaultEncoding" value="utf-8"></property>
</bean>

使用poi插件解析excel文件并封装成对应的实体类对象执行插入操作

代码
前端(jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// 设置动态初始访问路径(这里本地是http://127.0.0.1:8080/crm/)
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<title>演示文件上传</title>
</head>
<body>
<form action="workbench/activity/fileUpload" method="post" enctype="multipart/form-data">
<input type="file" name="myFile"><br>
<input type="text" name="upload_by"><br>
<%-- <input type="button" value="提交">--%>
<button>提交</button>
</form>
</body>
</html>

HSSFUtil
package com.mtf.common.util;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;

public class HSSFUtil {
public static String isType(HSSFCell cell){
//遍历每一行的所有列的值(之前需要判断每一列的“数据类型”)
if (cell.getCellType()== HSSFCell.CELL_TYPE_STRING){
return cell.getStringCellValue();
}
if (cell.getCellType()== HSSFCell.CELL_TYPE_NUMERIC){
return cell.getNumericCellValue()+"";
}
if (cell.getCellType()==HSSFCell.CELL_TYPE_ERROR){
return cell.getErrorCellValue()+"";
}
if (cell.getCellType()==HSSFCell.CELL_TYPE_BOOLEAN){
return cell.getBooleanCellValue()+"";
}
return null;
}
}

Controller层
@RequestMapping("/workbench/activity/fileUpload")
@ResponseBody
public Object fileUpload(MultipartFile myFile,HttpSession session) {
ResultObject resultObject = new ResultObject();
try {
/*
* 主要分为两大部分:
* 1、文件上传至服务器
* 2、Java解析服务器上的excel文件,解析数据并封装成对应的实体类对象进行添加操作
* */

//获取上传的文件名(包含扩展名)
// String originalFilename = myFile.getOriginalFilename();
User user = (User) session.getAttribute(ResultObjectConstant.Session_USER);

//模拟:把上传的文件写到服务端(从这里开始优化:内存-》磁盘-》内存 内存-》内存)
// if (originalFilename!=null){
// File file = new File("E:\\java\\CRM\\服务端", originalFilename);
// myFile.transferTo(file);
// }
//
// System.out.println("这里被执行了吗?");
// //解析上传到服务端的excel文件
// FileInputStream fileInputStream = new FileInputStream(new File("E:\\java\\CRM\\服务端", originalFilename));

//优化后
InputStream inputStream = myFile.getInputStream();

// System.out.println(fileInputStream+"--------------");
HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
HSSFSheet sheet = workbook.getSheetAt(0);
HSSFRow row = null;
HSSFCell cell = null;
ArrayList<Activity> activityArrayList = new ArrayList<>();
//封装数据
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
row = sheet.getRow(i);

Activity activity = new Activity();

activity.setId(UuidUtil.createUUID());//活动id
activity.setCreateTime(DateUtil.DateToStr(new Date()));//活动创建时间
activity.setCreateBy(user.getId());//活动创建者id
activity.setOwner(user.getId());//活动所选者名称

for (int j = 0; j < row.getLastCellNum(); j++) {
switch (j){
//row.getCell(0).getStringCellValue():注意这里,获取某一单元格的值之前,需要 "判断" 该单元格的数据是什么类型
//如果是支付串类型则获取单元格的值:getStringCellValue()方法
//如果是布尔类型:getBooleanCellValue()方法
//case 0:activity.setName(row.getCell(0).getStringCellValue());
case 0:activity.setName(HSSFUtil.isType(row.getCell(0)));
case 1:activity.setStartDate(HSSFUtil.isType(row.getCell(1)));
case 2:activity.setEndDate(HSSFUtil.isType(row.getCell(2)));
case 3:activity.setCost(HSSFUtil.isType(row.getCell(3)));
case 4:activity.setDescription(HSSFUtil.isType(row.getCell(4)));
}
}
activityArrayList.add(activity);
}

int i = activityService.insertActivityByFile(activityArrayList);
if (i>0){
resultObject.setCode(ResultObjectConstant.ResultObject_Code_SUCCESS);
resultObject.setMessage(i+"条市场活动,上传成功!");
resultObject.setRetData(i);
}else {
resultObject.setCode(ResultObjectConstant.ResultObject_Code_ERROR);
resultObject.setMessage("系统繁忙,请稍后重试!");
}
} catch (IOException e) {
e.printStackTrace();
resultObject.setCode(ResultObjectConstant.ResultObject_Code_ERROR);
resultObject.setMessage("系统繁忙,请稍后重试!");
}
return resultObject;
}

参考文章:http://blog.ncmem.com/wordpress/2023/12/13/javaweb%e9%a1%b9%e7%9b%ae%e5%bc%80%e5%8f%91%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e4%b8%8e%e4%b8%8b%e8%bd%bd%e5%8a%9f%e8%83%bd%e5%ae%9e%e7%8e%b0/

欢迎入群一起讨论