一、文档上传
1.导入依赖
pom.xml文件中导入依赖
<!-- 文档上传依赖 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
2. 配置 文档上传解析器
在 spring-mvc.xml 中配置文件上传解析器。
<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver ">
<!-- 设置上传文件的最大尺寸为 5MB=5x1024x1024 字节单位 -->
<property name="maxUploadSize" value="5242880"/>
</bean>
3. 配置 文档上传工具类
package com.oa.util;
import com.oa.bean.Doc;
import com.oa.service.DocService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
public class FileUpLoadUtils { //文件上传工具类
@Autowired
DocService docService;
/**
* 文件上传方法
*/
public static DataResults Fileupload(MultipartFile file, HttpServletRequest request, Doc doc, DocService docService) {
try {
//1.获取原始文件名 ( 获取"原始文件名")
String uploadFileName = file.getOriginalFilename();
System.out.println("要上传的原始文件名字是:" + uploadFileName);
//2.截取文件扩展名
String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1, uploadFileName.length());
//3.把文件加上随机数,防止文件重复
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
//4.生成的新的服务器文件名
String newfileName = uuid + "." + extendName;
System.out.println("生成的新的服务器文件名是:" + newfileName); //防止服务器文件名重名
//5.获取真实的服务器文件上传地址 (文件的存储位置)
String filePath = request.getServletContext().getRealPath("S:\\File") + "/" + newfileName;
System.out.println("服务器运行目录,最终上传的路径:" + filePath);
//6.执行上传
//方法中参数为: 该上传文件要存储的"文件夹" 和 该文件的"名称"以及"后缀"
file.transferTo(new File(filePath));
System.out.println("文件上传结束!");
//新增对象到数据库
doc.setFileName(newfileName);
boolean b=docService.save(doc);
// DataResults : 数据结果工具类,作用: 显示方法的执行状态,该方法中参数为
// ResultCode: 状态码枚举
if (b) {
return DataResults.success(ResultCode.SUCCESS);
} else {
return DataResults.fail(ResultCode.FAIL);
}
} catch (
IOException e) {
e.printStackTrace();
return DataResults.fail(ResultCode.FAIL);
}
}
}
4. 配置后端代码 ( 来实现文档的上传 )
4.1配置(controller层) 后端代码
/**
* 文档上传
*/
@ResponseBody
@PostMapping("/saveDocument")
public DataResults saveDocument(MultipartFile file, HttpServletRequest request, Doc doc) {
System.out.println("doc=" + doc);
//调用文件上传工具类 上传文件
DataResults dataResults = FileUpLoadUtils.Fileupload(file, request, doc, docService);
return dataResults;
}
4.2配置(bean层) Doc对象
package com.oa.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.oa.util.DateUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data //设置get、set方法
@AllArgsConstructor //全参数构造方法
@NoArgsConstructor //没参数构造方法
/*
用来将指定的数据库表和 JavaBean(一般为与数据库中表相对应的对象/类) 进行映射,@TableName是mybatis-plus中的注解,
主要是实现实体类型和 数据库中的表实现映射,将两者联系起来("tb_user")
*/
@TableName("tb_doc")
public class Doc {
@TableId(value="id",type= IdType.AUTO) //type=IdType.AUTO : 设置id自增
private Integer id;
private String createDate=DateUtils.nowTime();
@TableField("fileName")
private String fileName;
private String remark;
private String title;
private Integer uid;
private Integer del=0;
@TableField(exist = false) //额外的拓展字段
private Users users;
}
5. 配置前端代码 ( 来实现文档的上传 )
5.1配置配置(.jsp页面中) 前端代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<head>
<title>人事管理系统</title>
<!--引入bootstrap -->
<link href="/css/bootstrap.min.css" rel="stylesheet">
<!--引入layui -->
<link href="/layui/css/layui.css" rel="stylesheet">
</head>
<body>
<br/><br/>
<form class="layui-form" id="uploadForm">
<!--文档标题 -->
<div class="layui-form-item" style="margin-top: 5px">
<label class="layui-form-label" style="width: 100px">文件标题 </label>
<div class="layui-input-block" style="margin-right: 50px">
<input class="form-control" name="title" placeholder="请输入文件标题" type="text" lay-verify="title" id="title"/>
</div>
</div>
<!--文件描述 -->
<div class="layui-form-item" style="margin-top: 5px">
<label class="layui-form-label" style="width: 100px">文件描述</label><br>
<div class="layui-input-block" style="margin-right: 50px">
<textarea type="text" class="form-control" placeholder="请简单描述文件" rows="5" cols="10" name="remark"
id="remark"></textarea>
</div>
</div>
<!--上传文件 -->
<div class="layui-form-item" style="margin-top: 5px">
<label class="layui-form-label" style="width: 110px">请选择文件</label>
<div class="layui-input-inline">
<button type="button" class="btn-success btn" id="upload"><i class="layui-icon"></i>上传文件</button>
</div>
</div>
<!--按钮组 -->
<div class="layui-form-item" style="margin-top: 5px">
<div class="layui-input-inline" style="margin-left: 24px">
<button class="btn-sm btn btn-primary" id="submit" type="button">上传</button>
<button class="btn btn-sm btn-warning" type="reset">重置</button>
</div>
</div>
</form>
<!--引入jquery -->
<script src="/js/jquery-3.1.1.min.js" charset="UTF-8"></script>
<!--引入layui.js -->
<script src="/layui/layui.js" charset="UTF-8"></script>
<script type="text/javascript">
layui.use(['form', 'layer', 'upload'], function () {
var form = layui.form,
layer = layui.layer,
upload = layui.upload;
form.verify({
title: function (value) {
if (value.length == 0) {
return '标题不能为空哦';
}
}
});
var uploadInit = upload.render({
elem: '#upload',
url: '/doc/saveDocument',
accept: 'file', //与后端 MultipartFile file 中 file 名称一致
auto: false,
data: {title:'w',remark:'s',uid:0},
bindAction: '#submit',
before: function () {
uploadInit.config.data.title = $("#title").val(); //
uploadInit.config.data.remark = $("#remark").val();
uploadInit.config.data.uid = ${sessionScope.loginUser.id};
},
done: function (result) {
if (result.code == 200) {
layer.msg('上传成功', {icon: 1},function () {
window.location.href = "/jsp/doc-doc";
});
}else{
layer.msg('上传失败', {icon: 2});
}
},
error: function () {
layer.msg('上传失败', {icon: 2});
}
});
});
</script>
</body>
5.2“文件上传页面”展示
6. 配置 DataResults工具类 和 ResultCode枚举
6.1 配置 DataResults工具类
package com.oa.util;
import lombok.Data;
/**
* DataResults 配合 ResultCode 来使用,来为后端返回操作的状态/数据结果信息给前端
* DataResults中的方法的参数为ResultCode枚举中的内容
*/
@Data
public class DataResults { // DataResults: 数据结果/操作状态
private int code; //状态码
private String msg; //状态具体描述信息
private Object data; //返回的数据
private DataResults(int code, String msg) {
this.code = code;
this.msg = msg;
}
public static DataResults success(ResultCode resultCode){
// resultCode.getCode(), resultCode.getMsg() ---得到传入枚举的code 和 msg信息,并给DataResults类
DataResults resultCommon = new DataResults(resultCode.getCode(), resultCode.getMsg());
return resultCommon; //返回这个对象
}
public static DataResults success(ResultCode resultCode, Object data){
DataResults success = success(resultCode);
success.setData(data);
return success;
}
public static DataResults fail(ResultCode resultCode){
return success(resultCode);
}
}
6.2 配置 ResultCode 枚举
package com.oa.util;
public enum ResultCode { // ResultCode: 结果代码/状态码
SUCCESS(200,"请求成功"),
NO_DELETE(800,"数据在使用中,勿删除"),
FAIL(500,"请求失败"),
TIMEOUT(505,"支付超时"),
REGISTER_SUCCESS(200,"注册成功"),
USERNAME_NO_REPEAT(200,"用户名可用"),
ADD_FAV_SUCCESS(200,"收藏成功!"),
REMOVE_SUCCESS(200,"移除成功!"),
CODE_FAIL(9001,"验证码错误"),
LOGIN_FAIL(9002,"用户名或密码错误"),
NO_LOGIN(9003,"请先登录"),
NO_CHECK(9090,"验证失败"),
REGISTER_FAIL(9005," 注册失败"),
USERNAME_REPEAT(9006," 用户名重复"),
LOGIN_FORBID(9007,"用户被禁用"),
NO_RIGTHS(403,"暂无权限操作"),
@SuppressWarnings("all")
REPASSWORD_ERROR(9004,"两次密码不一致"),
PASSWORD_ERROR(9008,"原密码错误"),
PASSWORD_EMPTY(9009,"密码不能为空");
private int code;
private String msg;
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
ResultCode(int code, String msg){
this.code=code;
this.msg=msg;
}
}
二、文档下载
1. 配置 文档下载工具类
package com.oa.util;
import com.oa.bean.Doc;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
public class FileDownLoadUtils { //文档下载工具类
public static ResponseEntity<byte[]> FileDownLoad(Integer id, Doc doc ,HttpServletRequest request) {
//获得要下载的地址
String path = request.getSession().getServletContext().getRealPath("doc");
File file = new File(path, doc.getFileName());
if (file.exists()) {
try {
//设置请求头
HttpHeaders headers = new HttpHeaders();
/**
* 1.用title(存在中文)为文件名,可能会有乱码问题
*
* 2.用fileName(不存在中文 )为文件名,不会有乱码问题
* 如: String downName = new String(doc.getFileName().getBytes("utf-8"), "ISO-8859-1");
* ---要保证没有乱码问题可第二种方式
*
*/
//文件下载的名字, 可能存在乱码问题
String newFileName = doc.getTitle() + "." + doc.getFileName().split("\\.")[1];
String downName = new String(newFileName.getBytes("utf-8"), "ISO-8859-1");
// 设置以附件的形式下载
headers.setContentDispositionFormData("attachment", downName);
// 设置文件内容以流的形式来下载
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// 用springmvc 提供的下载方式
ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
return responseEntity;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
2. 配置后端代码 ( 来实现文档的下载 )
2.1配置(controller层) 后端代码
/**
* 下载文档
*/
@ResponseBody
@RequestMapping("/downloadDocument")
public ResponseEntity<byte[]> downloadDocument(Integer id, HttpServletRequest request) {
//获得该doc对象
Doc doc = docService.getById(id);
//用文件下载工具类 下载文件
ResponseEntity<byte[]> responseEntity = FileDownLoadUtils.FileDownLoad(id, doc, request);
return responseEntity;
}
3. 配置前端代码 ( 来实现文档的下载 )
3.1配置配置(.jsp页面中) 前端代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="utf-8">
<title>人事管理系统</title>
<!-- jq -->
<script src="../js/jquery-3.1.1.min.js"></script>
<!-- bootstrap -->
<link href="../css/bootstrap.min.css" rel="stylesheet">
<script src="../js/bootstrap.min.js"></script>
<!-- 分页插件 -->
<link href="../css/bootstrap-table.min.css" rel="stylesheet">
<script src="../js/bootstrap-table.js"></script>
<script src="../js/bootstrap-table-locale-all.min.js"></script>
<!--layer -->
<link href="../js/layer/theme/default/layer.css" rel="stylesheet">
<style type="text/css">
.panel {
margin-left: -48px;
width: 1145px;
}
.col-sm-12 {
margin-left: -60px;
}
thead {
background: #428bca;
color: white;
}
</style>
</head>
<body>
<div class="container" style="margin-top: 5px">
<div class="row">
<!--!查询区 -->
<div class="panel panel-default">
<div class="panel-heading"
style="background-color: #428bca; color: white">查询条件</div>
<div class="panel-body form-group" style="margin-bottom: 0px;">
<label class="col-sm-2 control-label"
style="text-align: right; margin-top: 5px">文档标题:</label>
<div class="col-sm-2">
<input type="text" class="form-control" name="name" id="search_docname" />
</div>
<div class="col-sm-1 col-sm-offset-4">
<button class="btn btn-primary" class="search" type="button" id="search_btn" style="background-color: #0767C8">搜索</button>
</div>
</div>
</div>
<div id="toolbar" class="btn-group">
<%--<button id="btn_edit" type="button" class="btn btn-primary" >--%>
<%--<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>修改--%>
<%--</button>--%>
<button id="btn_delete" type="button" class="btn btn-danger"
style="margin-left: 10px">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>批量删除
</button>
</div>
<!-- 表格 -->
<div class="col-sm-12">
<table class="table table-striped table-bordered table-hover"
id="table"></table>
</div>
</div>
</div>
<script src="../js/layer/layer.js"></script>
<script type="text/javascript">
//获取选中的所有行的id
function getIds() {
return $.map($("#table").bootstrapTable('getSelections'), function (row) {
return row.id;
})
}
/**
* 批量删除文档
*/
$("#btn_delete").click(function () {
var ids = getIds();
if (ids.length < 1) {
layer.alert('请选择至少一个文档!', {
skin: 'layui-layer-lan'
, closeBtn: 0
})
} else {
layer.confirm('确定删除这些文档吗??', {
btn: ['是的', '按错了'] //可以无限个按钮
}, function () {
//确定按钮的回调函数
var url = "/doc/removeDocuments";
$.ajax({
url: url,
data: "ids="+ids,
type: "post",
dataType: "json",
success:function(result){
if(result.code==200){
alert("删除成功!");
$("#table").bootstrapTable("refresh", {url: '/doc/page'});
layer.closeAll("dialog");
}else{
alert("系统异常!");
}
},
error: function () {
$("#table").bootstrapTable("refresh", {url: '/doc/page'});
layer.closeAll("dialog");
}
})
})
}
});
/**
* 删除文档
*/
function deleteone(id) {
layer.confirm('确定删除这个文档吗??', {
btn: ['是的', '按错了'] //可以无限个按钮
}, function () {
//确定按钮的回调函数
$.getJSON("/doc/removeDoc/"+id,function (result) {
//alert(JSON.stringify(result));
if(result.code==200){
alert("删除成功!");
//window.location.reload();
$("#table").bootstrapTable("refresh", {url: '/doc/page'});
layer.closeAll("dialog");
}else{
alert("系统异常!");
}
});
});
}
class BstpTable {
constructor(obj) {
this.obj = obj;
}
/**
* 异步分页
*/
inint() {
//---先销毁表格 ---
this.obj.bootstrapTable('destroy');
//---初始化表格,动态从服务器加载数据---
this.obj.bootstrapTable({
//【发出请求的基础信息】
url: '/doc/page',
method: 'post',
contentType: "application/x-www-form-urlencoded",//必须有
//【查询设置】
/* queryParamsType的默认值为 'limit' ,在默认情况下 传给服务端的参数为:offset,limit,sort
设置为 '' 在这种情况下传给服务器的参数为:pageSize,pageNumber */
queryParamsType: '',
queryParams: function queryParams(params) {
//自定义传递的参数
var param = {
pageNumber: params.pageNumber,
pageSize: params.pageSize,
title: $("#search_docname").val() //进行异步分页 模糊查询的条件
};
return param;
},
//【其它设置】
locale: 'zh-CN',//中文支持
pagination: true,//是否开启分页(*)
striped: true,
pageNumber: 1,//初始化加载第一页,默认第一页
pageSize: 5,//每页的记录行数(*)
pageList: [5, 10, 15],//可供选择的每页的行数(*)
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
showRefresh: true,//刷新按钮
showToggle: true,//卡片视图
toolbar: '#toolbar',//工具栏
//【样式设置】
height: 384,
//【设置列】
columns: [
{
title: '全选',
field: 'select',
//复选框
checkbox: true,
width: 25,
align: 'center',
valign: 'middle'
},
{field: 'title', title: '标题'},
{field: 'createDate', title: '创建时间'},
{field: 'users.username', title: '创建人'},
{field: 'remark', title: '描述'},
{
field: 'tool', title: '操作', align: 'center',
formatter: function (value, row, index) {
var element = "<button data-id='" + row.id + "' οnclick='deleteone(" + row.id + ")' class='btn btn-danger btn-sm'>删除</button> ";
return element;
}
},
{
field: 'download', title: '下载', align: 'center',
formatter: function (value, row, index) {
var element = "<a href='/doc/downloadDocument?id="+row.id+"'><img class='btn btn-success btn-sm' src='../images/download_icon.png' /></a>";
return element;
}
}
]
})
}
}
//初始化表格
var bstpTable = new BstpTable($("table"));
bstpTable.inint({})
//查询按钮的逻辑
$("#search_btn").click(function () {
$("#table").bootstrapTable("refresh", {url: '/doc/page'})
})
</script>
</body>
</html>