前言
本文实现了,前端页面上传单个文件到项目文件夹,数据库保存相对路径,并且下载为zip文件等功能。
一:上传
具体功能:点击附件框,选择文件,上传至项目文件夹
1.1:html
<form class="formImgdata" action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" class="file-upload-form" multiple value=""/>
</form>
<div class="form-control-tag">
<span class="label-tag">附件<em>*</em></span>
<input type="hidden" name ="ENCLOSURE" id="ENCLOSURE" value=""/>
<div class="uploadimg-cont">
<div class="form-upload"></div>
</div>
</div>
1.2:js
// 添加附件
$('.uploadimg-cont').on({
click: function(){
//模拟点击,弹出选择文件窗口
$('.formImgdata').find('.file-upload-form').click();
}
}, '.form-upload');
//文件选择,用change监听变化
$('.formImgdata').on({
change: function(){
var _this = $(this);
var file = this.files;
for (var i = 0; i < file.length; i++) {
//使用formData打包单个文件。当然,也可以把其他参数,文件打包在一起传递到控制层
var formData = new FormData();
formData.append('file', this.files[i]);
$.ajax({
type: 'post',
url: '<%=basePath%>studenttask/upload',
data: formData,
mimeType: "multipart/form-data",
contentType: false,
processData: false
}).success(function (data) {
//上传成功,反显文件
var res = JSON.parse(data);
if (res.success === true) {
var old_name = res.old_name
if(isImg(old_name)){
$('.uploadimg-cont').append('<div class="z_addImg" data-filepath="'+res.fileName+'"><img src="' + res.fileName + '"><div class="delBtn"><i class="feather icon-x"></i></div></div>');
}else{
$('.uploadimg-cont').append('<div class="z_addImg" data-filepath='+res.fileName+'>' + res.old_name + '<div class="delBtn"><i class="feather icon-x"></i></div></div>');
}
}else{
};
//成功提交
}).fail(function (jqXHR, textStatus, errorThrown) {
//错误信息
});
};
// $(this).val('');
}
}, '.file-upload-form');
//删除文件,注意文件已上传。删除的只是要保存的数据的文件路径
$('.uploadimg-cont').on({
click: function(){
$(this).parents('.z_addImg').remove();
}
}, '.delBtn');
//图片和其他文件分开处理,反显到页面
function extension (name){
var ext = null;
var name = name.toLowerCase();
var i = name.lastIndexOf(".");
if(i > -1){
var ext = name.substring(i);
}
return ext;
}
function contain (obj){
var imgExt = new Array(".png",".jpg",".jpeg",".bmp",".gif");
for(var i=0; i<imgExt.length; i++){
if(imgExt[i] === obj)
return true;
}
return false;
};
function isImg(filename){
var ext = extension(filename);
if(contain(ext)){
return true;
}
return false;
}
1.3:java
//上传附件,为便于理解,我调试了代码,把每个部分的值列出
@RequestMapping(value="/upload")
@ResponseBody
public PageData upload(MultipartFile file){//用MultipartFile即可接受单个文件,当formData打包了文件,参数等时,也可以用HttpServletRequest接受,
PageData pd = new PageData();//项目内封装类,可以当做map理解
//20191218
String rq = Tools.date2Str(new Date(), "yyyyMMdd");
//新华.txt
String old_name = file.getOriginalFilename();
//D:\tts9\workspace\yxt\yxt\src\main\webapp\uploadFiles/file/20191218/
String path = PathUtil.getProjectpath() +Const.FILEPATHFILE+rq+"/";
//1576665807199_新华
String fileName = System.currentTimeMillis()+"_"+old_name.substring(0,old_name.indexOf("."));
String newFileName ="";
try {
newFileName = FileUpload.fileUp(file, path, fileName);
pd.put("success", true);
pd.put("msg", "上传成功");
} catch (Exception e) {
e.printStackTrace();
pd.put("success", false);
pd.put("msg", "文件上传失败,请联系管理员");
}
pd.put("fileName", Const.FILEPATHFILE+rq+"/"+newFileName);
pd.put("old_name", old_name);
return pd;
}
public static String fileUp(MultipartFile file, String filePath, String fileName){
String extName = ""; // 扩展名格式:
try {
if (file.getOriginalFilename().lastIndexOf(".") >= 0){
//.txt
extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
}
copyFile(file.getInputStream(), filePath, fileName+extName).replaceAll("-", "");//文件转输入流
} catch (IOException e) {
System.out.println(e);
}
return fileName+extName;
}
/**
* 写文件到当前目录的upload目录中
* @param in
* @param fileName
* @throws IOException
*/
public static String copyFile(InputStream in, String dir, String realName)
throws IOException {
//D:\tts9\workspace\yxt\yxt\src\main\webapp\uploadFiles/file/20191218/
//1576665807199_新华.txt
File file = mkdirsmy(dir,realName);
FileUtils.copyInputStreamToFile(in, file);
in.close();
return realName;
}
/**判断路径是否存在,否:创建此路径
* @param dir 文件路径
* @param realName 文件名
* @throws IOException
*/
public static File mkdirsmy(String dir, String realName) throws IOException{
//D:\tts9\workspace\yxt\yxt\src\main\webapp\uploadFiles/file/20191218/
//1576665807199_新华.txt
File file = new File(dir, realName);
if (!file.exists()) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
file.createNewFile();
}
return file;
}
public static void copyInputStreamToFile(InputStream source, File destination) throws IOException {
try {
FileOutputStream output = openOutputStream(destination);//输出流
try {
IOUtils.copy(source, output);
output.close(); // don't swallow close Exception if copy completes normally
} finally {
IOUtils.closeQuietly(output);
}
} finally {
IOUtils.closeQuietly(source);
}
}
public static int copy(InputStream input, OutputStream output) throws IOException {
long count = copyLarge(input, output);
if (count > Integer.MAX_VALUE) {
return -1;
}
return (int) count;
}
public static long copyLarge(InputStream input, OutputStream output)
throws IOException {
return copyLarge(input, output, new byte[DEFAULT_BUFFER_SIZE]);//缓冲数组
}
public static long copyLarge(InputStream input, OutputStream output, byte[] buffer)
throws IOException {
long count = 0;
int n = 0;
while (EOF != (n = input.read(buffer))) {//读取
output.write(buffer, 0, n);
count += n;
}
return count;
}
二:保存数据到数据库
文件虽然上传,但数据库中没有信息,无法实现下载,保存选择的文件所上传到的项目文件的相对路径即可,此处采用表单提交
2.1:js
//附件判断
if($(".z_addImg").length>0){
}else{
$(".uploadimg-cont").tips({
side:3,
msg:'请上传文件',
bg:'#AE81FF',
time:2,
x:40,
y:20
});
$(".uploadimg-cont").focus();
return false;
}
//路径
var ENCLOSURE = "";
$(".z_addImg").each(function(){
ENCLOSURE += $(this).attr("data-filepath")+",";
})
ENCLOSURE=ENCLOSURE.substring(0,ENCLOSURE.length-1);
$("#ENCLOSURE").val(ENCLOSURE);
2.2:java
/**保存
* @param
* @throws Exception
*/
@RequestMapping(value="/save")
@RequiresPermissions("studenttask:add")
public String save(Model model) throws Exception{
PageData pd = new PageData();
pd = this.getPageData();//可获得表单提交的参数
Session session = Jurisdiction.getSession();
User user = (User)session.getAttribute(Const.SESSION_USER); //读取session中的用户信息(单独用户信息)
String username = user.getUSERNAME();
pd.put("CREATER", username); //创建人
pd.put("CREATE_DATE", Tools.date2Str(new Date())); //创建时间
pd.put("UPDATE_DATE", Tools.date2Str(new Date())); //更新日期
pd.put("STUDENTTASK_ID", this.get32UUID()); //主键
studenttaskService.save(pd);
model.addAttribute("msg","success");
return "transferPage";
}
/**
* new PageData对象
* @return
*/
public PageData getPageData() {
return new PageData(this.getRequest());
}
/**
* 得到request对象
* @return
*/
public HttpServletRequest getRequest() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
return request;
}
//服务层
/**新增
* @param pd
* @throws Exception
*/
public void save(PageData pd)throws Exception;
//实现层
/**新增
* @param pd
* @throws Exception
*/
public void save(PageData pd)throws Exception{
studenttaskMapper.save(pd);
}
//mapper
/**新增
* @param pd
* @throws Exception
*/
void save(PageData pd);
//xml
<!-- 修改 -->
<update id="edit" parameterType="pd">
update
<include refid="tableName"></include>
set
TASK_NAME = #{TASK_NAME},
COURSE = #{COURSE},
GRADE = #{GRADE},
CLASS = #{CLASS},
START_DATE = #{START_DATE},
END_DATE = #{END_DATE},
CONTEXT = #{CONTEXT},
ENCLOSURE = #{ENCLOSURE},
UPDATE_DATE = #{UPDATE_DATE},
STUDENTTASK_ID = STUDENTTASK_ID
where
STUDENTTASK_ID = #{STUDENTTASK_ID}
</update>
数据库得到数据(两个相对路径:一个txt,一个图片)
前台页面
三:下载
3.1:html
带个主键id过去,查数据库,得到ENCLOSURE (图片路径,多个图片路径用“,”隔开)
<a title="附件下载" onclick="javascript:window.location.href='studenttask/downFile?STUDENTTASK_ID=${var.STUDENTTASK_ID}'" style="cursor:pointer;"></a>
3.2:java
//下载附件
@RequestMapping(value="downFile")
public void downFile(HttpServletResponse response) throws Exception{
PageData pd = new PageData();
pd = getPageData();
PageData pageData = studenttaskService.findById(pd);
String ENCLOSURE = pageData.getString("ENCLOSURE");
if(!StringUtils.isEmpty(ENCLOSURE)){
String[] ENCLOSUREArr =ENCLOSURE.split(",");
String filePaths = PathUtil.getProjectpath()+"uploadFiles"+"/"+this.getCurrentUserName()+System.currentTimeMillis();
File file = new File(filePaths);
if(!file.exists()){
file.mkdir();
}else {
FileUtil.delFile(filePaths);
file.mkdir();
}
for(String aa:ENCLOSUREArr){//遍历文件
String filePath = PathUtil.getProjectpath()+aa;
String fileName = aa.substring(aa.lastIndexOf("/"), aa.length());
//把文件复制到一个要压缩的文件夹
FileUpload.copyFile(new File(filePath), new File(filePaths+"/"+fileName));
}
if(FileZip.zip(filePaths, filePaths+".zip")){//压缩
FileDownload.fileDownload(response, filePaths+".zip", "附件.zip");
FileUtil.delFile(filePaths+".zip");//删除压缩包
FileUtil.deleteDirectory(filePaths);//删除文件夹
}
}
}
public static void copyFile(File sourceFile,File targetFile)throws IOException{
// 新建文件输入流并对它进行缓冲
FileInputStream input = new FileInputStream(sourceFile);
BufferedInputStream inBuff=new BufferedInputStream(input);
// 新建文件输出流并对它进行缓冲
FileOutputStream output = new FileOutputStream(targetFile);
BufferedOutputStream outBuff=new BufferedOutputStream(output);
// 缓冲数组
byte[] b = new byte[1024 * 5];
int len;
while ((len =inBuff.read(b)) != -1) {
outBuff.write(b, 0, len);
}
// 刷新此缓冲的输出流
outBuff.flush();
//关闭流
inBuff.close();
outBuff.close();
output.close();
input.close();
}
public static Boolean zip(String inputFileName, String zipFileName) throws Exception {
zip(zipFileName, new File(inputFileName));//文件转输入流
return true;
}
private static void zip(String zipFileName, File inputFile) throws Exception {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));//输出流
zip(out, inputFile, "");
out.flush();
out.close();
}
//递归压缩
private static void zip(ZipOutputStream out, File f, String base) throws Exception {
if (f.isDirectory()) {
File[] fl = f.listFiles();
out.putNextEntry(new ZipEntry(base + "/"));
base = base.length() == 0 ? "" : base + "/";//文件名
for (int i = 0; i < fl.length; i++) {
zip(out, fl[i], base + fl[i].getName());
}
} else {
out.putNextEntry(new ZipEntry(base));
FileInputStream in = new FileInputStream(f);
int b;
while ((b = in.read()) != -1) {//逐个字节读取
out.write(b);
}
in.close();
}
}
//模拟浏览器下载
public static void
fileDownload(final HttpServletResponse response, String filePath, String fileName) throws Exception{
byte[] data = FileUtil.toByteArray2(filePath);
fileName = URLEncoder.encode(fileName, "UTF-8");
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream;charset=UTF-8");
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
outputStream.write(data);
outputStream.flush();
outputStream.close();
response.flushBuffer();
}