目录
(1)用的是Struts2的action,其中有对数据库的插入删除
1、网页效果图
2、jar包
文件上传的jar包为 bootstrap-fileinput-master,图片展示的jar包为 jquerySinlar,下载地址https://download.csdn.net/download/qq_27339781/10785735
3、网页代码
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@include file="/jpascommon/taglibs.jsp"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>blank</title>
<%-- <link href="<%=request.getContextPath() %>/jpascss/style.css" rel="stylesheet" type="text/css" /> --%>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" type="text/javascript"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" media="all" rel="stylesheet" type="text/css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" type="text/javascript"></script>
<link href="${ctx }/jpasscripts/bootstrap-fileinput-master/css/fileinput.css" media="all" rel="stylesheet" type="text/css"/>
<link href="${ctx }/jpasscripts/bootstrap-fileinput-master/themes/explorer-fa/theme.css" media="all" rel="stylesheet" type="text/css"/>
<script src="${ctx }/jpasscripts/bootstrap-fileinput-master/js/plugins/sortable.js" type="text/javascript"></script>
<script src="${ctx }/jpasscripts/bootstrap-fileinput-master/js/fileinput.js" type="text/javascript"></script>
<script src="${ctx }/jpasscripts/bootstrap-fileinput-master/themes/explorer-fa/theme.js" type="text/javascript"></script>
<script src="${ctx }/jpasscripts/bootstrap-fileinput-master/themes/fa/theme.js" type="text/javascript"></script>
<script type="text/javascript" src="${ctx}/jpasscripts/bootstrap-fileinput-master/js/locales/zh.js"></script>
<script src="${ctx}/jpasscripts/pic/sinlar.js"></script>
<style>
.data_box{
width:100%;
height:100%;
margin:10px auto;
}
.data_box ul li{
display:inline-block;
/* float: left; */
width:280px;
height:170px;
margin:10px;
}
.data_box ul li img{
width:100%;
}
body{
padding:0;
margin:0;
font-size: 14px;
color:#444;
}
*{
border:0;
padding:0;
margin:0;
list-style: none;
text-decoration:none;
}
td{
padding-left: 20px;
vertical-align: middle;
}
</style>
</head>
<body>
<div>
<div>
<form action="${ctx }/custFileAction!queryCustFile.action" method="post" class="form-search" id="myForm">
<table style="border:0px;background-color: #d9edf7;height:40px;width: 100%" >
<tr>
<td style="width: 100px;">
<label class="control-label" for="id">图片类型:</label>
</td>
<td >
<select name="custFileBean.type" id="type" style="width:134px" >
<c:forEach items="${typeList}" var="type">
<option value="${type.TYPE_ID }"
<c:if test="${ custFileBean.type == type.TYPE_ID}">selected</c:if>
>${type.TYPE_NAME }</option>
</c:forEach>
</select>
</td>
<td >
<input type="hidden" value="${custFileBean.custId}" name="custFileBean.custId" id="custId">
<input type="submit" class="btn btn-info btn-sm" value="查询"/>
<input type="button" class="btn btn-info btn-sm" value="上传" onclick="showUpload()"/>
<input type="button" class="btn btn-info btn-sm" value="下载压缩包" onclick="myExport()"/>
<%-- <a href="${ctx}/personal_getBaseInfo.action?userid=${custFileBean.custId}"><input type="button" class="btn btn-sm" value="返回"/> </a> --%>
</td>
</tr>
</table>
</form>
</div>
<div class="container kv-main" id="uploadDiv" style="display: none;">
<hr>
<div class="form-group">
<div class="file-loading">
<input id="file" type="file" multiple name="file" class="file" data-overwrite-initial="false" >
</div>
</div>
<hr>
</div>
<div >
<div class="data_box">
<ul>
<c:forEach items="${picList}" var="img">
<li>
<div style="position:relative;z-index:100">
<img class="data-img" src="${img.url}" />
<div style="position:absolute;top:0;right:0;">
<input type="button" value="×" style="width: 20px;height: 20px;background-color: white;cursor:pointer;" onclick="deleteImg('${img.id}')"/>
</div>
</div>
</li>
</c:forEach>
</ul>
</div>
</div>
</div>
</body>
<script>
//此方法是为为该元素绑定bootstrap-fileinput
$("#file").fileinput({
language:'zh',//中文
theme: 'fa',//主题
uploadAsync : true,//默认异步上传,就是一张图片一张图片的上传,如果为多张就同步
showUpload: true,//显示上传
showCaption: true,//显示预览
enctype:'multipart/form-data',
uploadUrl: '${ctx}/custFileAction!insertCustFile.action', // 异步上传的服务器地址
uploadExtraData:{"custFileBean.custId":$("#custId").val(),"custFileBean.type":$("#type").val()},//上传的其他数据
allowedFileExtensions: ['jpg', 'png', 'gif'],//上传限制的文件
overwriteInitial: false,
maxFileSize: 102400,//最大带下 100M
maxFilesNum: 10,//同意的最大文件数
//allowedFileTypes: ['image', 'video', 'flash'],
fileType: "any",
textEncoding: "UTF-8",
slugCallback: function (filename) {
return filename.replace('(', '_').replace(']', '_');
}
});
$("#file").on('fileuploaded', function(event, data, previewId, index) {//异步上传成功结果处理
//等待50毫秒去刷新页面
setTimeout("goFlush();", 50);
});
$("#file").on('fileerror', function(event, data, msg) {//异步上传失败结果处理
alert(data.response.message);
});
//涮新页面
function goFlush(){
location.href = "${ctx}/custFileAction!queryCustFile.action?custFileBean.custId="+$("#custId").val()+"&custFileBean.type="+$("#type").val();
}
//上传文件的元素是否显示
function showUpload(){
$("#uploadDiv").toggle();
}
//导出文件压缩包
function myExport(){
location.href = "${ctx}/custFileAction!downZipLoad.action?custFileBean.custId="+$("#custId").val()+"&custFileBean.type="+$("#type").val();
}
//删除文件
function deleteImg(id){
var msg = "您确定要删除该图片吗?";
if (confirm(msg)==true){
location.href = "${ctx}/custFileAction!deleteFile.action?custFileBean.id="+id;
}
}
</script>
4、java代码
(1)用的是Struts2的action,其中有对数据库的插入删除
public class CustFileAction extends BaseStruts2Action {
private static final long serialVersionUID = 1L;
protected final transient Logger log = LoggerFactory.getLogger(getClass());
private CustFileBean custFileBean;
private List<File> file ;
private List<String> fileFileName ;
private String downFileName;
private InputStream fileInputStream;
CustFileService custFileService = new CustFileServiceImpl();
/**
* 上传文件
* @return
*/
public void insertCustFile(){
Connection con = null;
boolean abortTransaction = false;
JsonResult json = null;
try {
json = new JsonResult();
custFileBean.setMan(getLoginUser().getId());
custFileBean.setTime(DateUtil.yyyyMMddHH_MM_SS(new Date()));
con = DbConnectionManager.getTransactionConnection();
String filePath = CrmConstrants.custPicPath+File.separator+custFileBean.getCustId()+File.separator+custFileBean.getType();
custFileBean.setName(file2FileName);
custFileService.insertCustFile(con, custFileBean);
FileUtils.uploadFile(filePath, file2, file2FileName);
json.setSuccAndMsg(true, "上传文件成功!");
} catch (Exception e) {
e.printStackTrace();
abortTransaction = true;
log.error("插入客户图片错误", e);
json.setSuccAndMsg(false, "上传文件失败!");
}finally{
DbConnectionManager.closeTransactionConnection(con, abortTransaction);
}
writeJson(json);
}
/**
* 查询已有文件
* @return
*/
//<Context path="/custPicDir" docBase="D:\KingRee\custPic" crossContext="true" reloadable="false" debug="0"/>这段代码加入tomcat的server.xml中
public String queryCustFile(){
try {
List<CustFileBean> fileList = custFileService.queryCustFileList(custFileBean);
List<Map<String, Object>> picList = new ArrayList<Map<String, Object>>();
for (int i = 0; i < fileList.size(); i++) {
String url = "/custPicDir"+File.separator+custFileBean.getCustId()+File.separator+fileList.get(i).getType()+File.separator+fileList.get(i).getName();
Map<String, Object> map = new HashMap<String, Object>();
map.put("url", url);
map.put("id", fileList.get(i).getId());
picList.add(map);
}
List<Map<String, Object>> typeList=FileUtils.getTypeList("804");
request.setAttribute("typeList", typeList);
request.setAttribute("picList", picList);
} catch (SQLException e) {
e.printStackTrace();
log.error("查询客户图片错误", e);
}
return "custFile";
}
/**
* 删除文件
* @return
*/
public String deleteFile(){
Connection con = null;
boolean abortTransaction = false;
try {
con = DbConnectionManager.getTransactionConnection();
CustFileBean custFileBean2 = custFileService.queryCustFileList(custFileBean).get(0);
String url = CrmConstrants.custPicPath+File.separator+custFileBean2.getCustId()+File.separator+custFileBean2.getType()+File.separator+custFileBean2.getName();
if(custFileService.deleteCustFile(con, custFileBean2)>0){
FileUtils.delete(url);
}
custFileBean.setId(null);
custFileBean.setCustId(custFileBean2.getCustId());
custFileBean.setType(custFileBean2.getType());
} catch (Exception e) {
e.printStackTrace();
abortTransaction = true;
log.error("删除客户图片错误", e);
return ERROR;
}finally{
DbConnectionManager.closeTransactionConnection(con, abortTransaction);
}
return queryCustFile();
}
/**
* 下载单个文件
* @return
*/
public String downLoad(){
try {
String downFileName2 =CrmConstrants.custPicPath+File.separator+custFileBean.getCustId()+File.separator+custFileBean.getType()+File.separator+custFileBean.getName();
downFileName=URLEncoder.encode(custFileBean.getName(), "UTF-8");
fileInputStream = new FileInputStream(downFileName2);
} catch (Exception e) {
e.printStackTrace();
log.error("下载客户图片错误", e);
}
return "downLoad";
}
/**
* 下载zip文件
* @return
*/
public String downZipLoad(){
try {
String downFileName2 =CrmConstrants.custPicPath+File.separator+custFileBean.getCustId()+File.separator+custFileBean.getType()+".zip";
FileUtils.fileToZip(CrmConstrants.custPicPath+File.separator+custFileBean.getCustId()+File.separator+custFileBean.getType(), CrmConstrants.custPicPath+File.separator+custFileBean.getCustId(), custFileBean.getType());
String name = FileUtils.getTypeMap("804").get(custFileBean.getType())+"";
downFileName=URLEncoder.encode(name+"附件"+".zip", "UTF-8");
fileInputStream = new FileInputStream(downFileName2);
} catch (Exception e) {
e.printStackTrace();
log.error("下载客户图片压缩包错误", e);
}
return "downZipLoad";
}
public String getDownFileName() {
return downFileName;
}
public void setDownFileName(String downFileName) {
this.downFileName = downFileName;
}
public InputStream getFileInputStream() {
return fileInputStream;
}
public void setFileInputStream(InputStream fileInputStream) {
this.fileInputStream = fileInputStream;
}
public CustFileBean getCustFileBean() {
return custFileBean;
}
public void setCustFileBean(CustFileBean custFileBean) {
this.custFileBean = custFileBean;
}
public List<File> getFile() {
return file;
}
public void setFile(List<File> file) {
this.file = file;
}
public List<String> getFileFileName() {
return fileFileName;
}
public void setFileFileName(List<String> fileFileName) {
this.fileFileName = fileFileName;
}
}
(2)bean类
public class CustFileBean implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String id;
private String custId;
private String time;
private String type;
private String man;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCustId() {
return custId;
}
public void setCustId(String custId) {
this.custId = custId;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMan() {
return man;
}
public void setMan(String man) {
this.man = man;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
(3)文件上传,下载的工具类
public class FileUtils {
/**
* 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下
* @param sourceFilePath :待压缩的文件路径
* @param zipFilePath :压缩后存放路径
* @param fileName :压缩后文件的名称
* @return
*/
public static void fileToZip(String sourceFilePath,String zipFilePath,String fileName){
// boolean flag = false;
File sourceFile = new File(sourceFilePath);
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
ZipOutputStream zos = null;
if(sourceFile.exists() == false){
System.out.println("待压缩的文件目录:"+sourceFilePath+"不存在.");
sourceFile.mkdir(); // 新建目录
}
try {
File zipFile = new File(zipFilePath + File.separator + fileName +".zip");
if(zipFile.exists()){
delete(zipFilePath + File.separator + fileName +".zip");
}
//System.out.println(zipFilePath + "目录下存在名字为:" + fileName +".zip" +"打包文件.");
File[] sourceFiles = sourceFile.listFiles();
if(null == sourceFiles || sourceFiles.length<1){
System.out.println("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");
}else{
fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte[] bufs = new byte[1024*10];
for(int i=0;i<sourceFiles.length;i++){
//创建ZIP实体,并添加进压缩包
ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
zos.putNextEntry(zipEntry);
//读取待压缩的文件并写进压缩包里
fis = new FileInputStream(sourceFiles[i]);
bis = new BufferedInputStream(fis, 1024*10);
int read = 0;
while((read=bis.read(bufs, 0, 1024*10)) != -1){
zos.write(bufs,0,read);
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally{
//关闭流
try {
if(null != bis) bis.close();
if(null != zos) zos.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void uploadFiles(String filePath, File[] files) throws Exception{
for(File file : files){
if(file != null){
uploadFile(filePath, file, null);
}
}
}
/**
* 上传文件
* @param filePath
* @param file
* @param newFileName
* @return
* @throws Exception
*/
public static String uploadFile(String filePath, File file, String newFileName) throws Exception{
String fileName = "";
try {
//获取到该文件的文件名
fileName = file.getName();
if(null!=newFileName && !"".equals(newFileName)){
/*
String suffix = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
if(!newFileName.endsWith(suffix)){
int n = newFileName.indexOf(".");
if(n != -1){
//去掉指定文件名的后缀名,并替换为所上传文件的文件名
newFileName = newFileName.substring(0, n);
}
fileName = newFileName + suffix;
}else{
fileName = newFileName;
}
*/
String suffix = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
int n = newFileName.lastIndexOf(".");
if(n!= -1){
fileName = newFileName;
}else{
fileName = newFileName + suffix;
}
}
//根据改文件的项目路径以及该文件的文件名创建一个file
File targetFile = new File(filePath);
//如果不存在则进行多级创建
if(!targetFile.exists()){
targetFile.mkdirs();
}
File saveFile = new File(filePath, fileName);
InputStream stream = new FileInputStream(file);
OutputStream bos = new FileOutputStream(saveFile);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.close();
stream.close();
} catch (Exception ex) {
throw new Exception("上传文件出错!", ex);
}
return fileName;
}
/**
* 删除文件,可以是文件或文件夹
*
* @param fileName
* 要删除的文件名
* @return 删除成功返回true,否则返回false
*/
public static boolean delete(String fileName) {
File file = new File(fileName);
if (!file.exists()) {
System.out.println("删除文件失败:" + fileName + "不存在!");
return false;
} else {
if (file.isFile())
return deleteFile(fileName);
else
return deleteDirectory(fileName);
}
}
/**
* 删除单个文件
*
* @param fileName
* 要删除的文件的文件名
* @return 单个文件删除成功返回true,否则返回false
*/
public static boolean deleteFile(String fileName) {
File file = new File(fileName);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
System.out.println("删除单个文件" + fileName + "成功!");
return true;
} else {
System.out.println("删除单个文件" + fileName + "失败!");
return false;
}
} else {
System.out.println("删除单个文件失败:" + fileName + "不存在!");
return false;
}
}
/**
* 删除目录及目录下的文件
*
* @param dir
* 要删除的目录的文件路径
* @return 目录删除成功返回true,否则返回false
*/
public static boolean deleteDirectory(String dir) {
// 如果dir不以文件分隔符结尾,自动添加文件分隔符
if (!dir.endsWith(File.separator))
dir = dir + File.separator;
File dirFile = new File(dir);
// 如果dir对应的文件不存在,或者不是一个目录,则退出
if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
System.out.println("删除目录失败:" + dir + "不存在!");
return false;
}
boolean flag = true;
// 删除文件夹中的所有文件包括子目录
File[] files = dirFile.listFiles();
for (int i = 0; i < files.length; i++) {
// 删除子文件
if (files[i].isFile()) {
flag = deleteFile(files[i].getAbsolutePath());
if (!flag)
break;
}
// 删除子目录
else if (files[i].isDirectory()) {
flag = deleteDirectory(files[i]
.getAbsolutePath());
if (!flag)
break;
}
}
if (!flag) {
System.out.println("删除目录失败!");
return false;
}
// 删除当前目录
if (dirFile.delete()) {
System.out.println("删除目录" + dir + "成功!");
return true;
} else {
return false;
}
}
}
5、strut2的xml中下载的配置
<action name="custFileAction" class="com.jinrui.crm.action.CustFileAction">
<result name="downLoad" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="contentDisposition">attachment;fileName="${downFileName}"</param>
<param name="inputName">fileInputStream</param>
</result>
<result name="downZipLoad" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="contentDisposition">attachment;fileName="${downFileName}"</param>
<param name="inputName">fileInputStream</param>
</result>
<result name="custFile">/pages/crmPersonal/custFile.jsp</result>
</action>
6、bootstrap-fileinput的一些参数
属性
属性名 | 属性类型 | 描述说明 | 默认值 |
language | String | 多语言设置,使用时需提前引入\locales文件夹下对应的语言文件,中文zh,引入语言文件必须放在fileinput.js之后 | 'en' |
showCaption | Boolean | 是否显示被选文件的简介 | true |
showBrowse | Boolean | 是否显示浏览按钮 | true |
showPreview | Boolean | 是否显示预览区域 | true |
showRemove | Boolean | 是否显示移除按钮 | true, |
showUpload | Boolean | 是否显示上传按钮 | true, |
showCancel | Boolean | 是否显示取消按钮 | true, |
showClose: | Boolean | 是否显示关闭按钮 | true |
autoReplace | Boolean | 是否自动替换当前图片,设置为true时,再次选择文件,会将当前的文件替换掉。 | false |
previewClass | String | 添加预览按钮的类属性 | ‘’ |
deleteUrl | String | 删除图片时的请求路径 | '' |
deleteExtraData | Object | 删除图片时额外传入的参数 | |
allowedFileTypes | Object | 接收的文件后缀,如['jpg', 'gif', 'png'],不填将不限制上传文件后缀类型 | null |
uploadUrl | String | 上传文件路径 | null |
uploadAsync | boolean | 是否为异步上传,一张一张的传,如果为多张就为同步 | true |
uploadExtraData |
| 上传文件时额外传递的参数设置 | {} |
minImageWidth | String | 图片的最小宽度 | null |
minImageHeight | String | 图片的最小高度 | null |
maxImageWidth | String | 图片的最大宽度 | null |
maxImageHeight | String | 图片的最大高度 | null |
minFileSize | number | 单位为kb,上传文件的最小大小值 | 0 |
maxFileSize | number | 单位为kb,如果为0表示不限制文件大小 | 0 |
resizeDefaultImageType | number | 调整默认图像类型 | 25600(25MB) |
minFileCount | number | 表示同时最小上传的文件个数 | 0 |
maxFileCount | number | 表示允许同时上传的最大文件个数 | 0 |
validateInitialCount | boolean | 验证初始计数 | false |
previewFileType | String | 预览文件类型,内置['image', 'html', 'text', 'video', 'audio', 'flash', 'object',‘other‘]等格式 | 'image |
elCaptionText | String | 设置标题栏提示信息 | null |
dropZoneEnabled | boolean | 是否显示拖拽区域 | true |
dropZoneTitleClass | String | 拖拽区域类属性设置 | 'file-drop-zone-title' |
textEncoding | String | 编码设置 | 'UTF-8' |
方法
方法名 | 参数 | 描述 |
fileerror |
| 异步上传错误结果处理 $('#uploadfile').on('fileerror', function(event, data, msg) { }); |
fileuploaded |
| 异步上传成功结果处理 $("#uploadfile").on("fileuploaded", function (event, data, previewId, index) { }) |
filebatchuploaderror |
| 同步上传错误结果处理 $('#uploadfile').on('filebatchuploaderror', function(event, data, msg) {
}); |
filebatchuploadsuccess |
| 同步上传成功结果处理 $('#uploadfile').on('filebatchuploadsuccess', function(event, data, previewId, index) {
}); |
filebatchselected |
| 选择文件后处理事件 $("#fileinput").on("filebatchselected", function(event, files) { }); |
upload |
| 文件上传方法 $("#fileinput").fileinput("upload"); |
fileuploaded |
| 上传成功后处理方法 $("#fileinput").
|
filereset |
|
|
fileclear |
| 点击浏览框右上角X 清空文件前响应事件 $("#fileinput").on("fileclear",function(event, data, msg){ }); |
filecleared |
| 点击浏览框右上角X 清空文件后响应事件 $("#fileinput").on("filecleared",function(event, data, msg){ }); |
fileimageuploaded |
| 在预览框中图片已经完全加载完毕后回调的事件 |