点击事件,打开上传的页面
<a href="javascript:void(0);" onclick="addAttachment(this)" class="ddBtn btnGreen" value="WayBill">
xxx附件
</a>
function addAttachment(e) {
var content = $(e).text().trim();
var type = $(e).attr("value");
var operateType = $("#operateType").val();
var companyCheckNo = $("#companyCheckNo").val();
art.dialog.open("/company-check/to-attachment-page?pageType="+ type +"&operateType="+ operateType + "&companyCheckNo=" + companyCheckNo , {
type: 'POST',
title: "添加" + content,
lock:true,
width: 500,
height: 300
});
}
/**
* 打开附件新增页面
*/
@RequestMapping("/to-attachment-page")
public String toAttachmentpage(Model model,String pageType,String operateType,String companyCheckNo){
model.addAttribute("operateType",operateType);
model.addAttribute("pageType",pageType);
//查询主表附件信息
List<UploadFileVO> uploadFileVOS = new ArrayList<>();
if ("showDetail".equals(operateType) || "edit".equals(operateType)){
List<UploadFileDTO> uploadFileDTOS = appCompanyCheckRpcService.getFileInfoByNo(companyCheckNo,pageType);
for (UploadFileDTO uploadFileDTO : uploadFileDTOS) {
uploadFileVOS.add(uploadFileDTO.convert(UploadFileVO.class));
}
}
model.addAttribute("uploadFileVOS",uploadFileVOS);
return "companycheck/app_company_check_attachment";
}
页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>主表附件</title>
<div th:replace="~{commons/head::common-header}"></div>
</head>
<body>
<div class="pA10">
<div class="whiteBox">
<input type="hidden" id="pageType" th:value="${pageType}"/>
<input type="hidden" id="operateType" th:value="${operateType}"/>
<form id="uploadForm" enctype="multipart/form-data">
<th:block th:if="${operateType == 'edit' || operateType == 'add'}">
<div class="row">
<div id="file">
<div>
<input type="file" id="uploadform-files" name="UploadForm[Files][]"
multiple>
<div id="fileName"></div>
</div>
</div>
</div>
</th:block>
<table class="commonTable editTable mT5 table">
<tbody id="files">
</tbody>
</table>
<table class="commonTable editTable mT5 table">
<tbody id="existingFiles">
<tr th:each="item: ${uploadFileVOS}">
<td class="hidden" th:id="${item?.id}"></td>
<td th:text="${item?.fileName}+ '(已上传)'"></td>
<td style="width: 10%"><input type="button" class="btn btnWhite downloadExisting" value="下载"></td>
<td style="width: 10%"><input type="button" class="btn btnRed deleteExisting" value="删除"></td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
<div th:replace="~{commons/head::common-js}"></div>
<script th:src="@{/project/js/express/companycheck/company_check_attachment.js}"></script>
<script>
var pageType = $("#pageType").val();
console.log("page:"+ pageType)
var fileList = art.dialog.data(pageType + "_attachment");
//打开弹窗时,加载未上传的文件
$.each(fileList, function (index, item) {
var fileName = item.name;
allFile.push(item);
$('#files').append( '<tr style="padding-top: 7px;">' +
'<td>'+fileName+'(未上传)'+'</td>' +
'<td style="width: 10%"></td>' +
'<td style="width: 10%"><input type="button" class="btn btnRed delete" value="删除"></td>' +
'</tr>');
//追加文件
formData.append('UploadForm[Files][]',item);
});
</script>
</body>
</html>
var fileList;
var allFile = [];
//FormData对象初始化
var form = document.getElementById("uploadForm");
var pageType = document.getElementById("pageType");
var formData = new FormData(form);
$("#uploadform-files").on('change', function (e) {
// var fileError = 0;
$('#files').empty();
fileList = e.currentTarget.files;
$.each(fileList, function (index, item) {
var fileName = item.name;
// var fileEnd = fileName.substring(fileName.indexOf("."));
//上传文件格式判断
// if (fileEnd == ".xlsx") {
allFile.push(item);
$('#files').append( '<tr style="padding-top: 7px;">' +
'<td>'+fileName+'(未上传)'+'</td>' +
'<td style="width: 10%"></td>' +
'<td style="width: 10%"><input type="button" class="btn btnRed delete" value="删除"></td>' +
'</tr>');
//追加文件
formData.append('UploadForm[Files][]',item);
// }
// else {
// fileError++;
// }
});
// if (fileError > 0) {
// alert("只能上传 “.xlsx” 格式的文件!");
// document.getElementById("upload-form").reset();
// return;
// }
var fileCount = $('#files').find('tr').length;
$('#fileName').html('共上传 ' + fileCount + ' 个文件');
art.dialog.data(pageType + "_attachment",fileList);
});
/** 删除未上传的文件*/
$('#files').on('click','.delete',function (e) {
var saveFile = [];
var deleteName = e.target.parentNode.previousElementSibling.previousElementSibling.textContent;
deleteName = deleteName.substring(0, deleteName.lastIndexOf('('));
// console.log("deleteName" + deleteName)
var deleteIndex;
//将不删除的放入数组中
$.each(allFile,function (index, item) {
if(item.name == deleteName){
deleteIndex = index;
}else {
saveFile.push(item);
}
});
allFile.splice(deleteIndex,1);
formData.delete('UploadForm[Files][]');
// 将不删除的数组追加的formData中
$.each(saveFile,function (index, item) {
formData.append('UploadForm[Files][]',item);
});
e.target.parentNode.parentNode.remove();
var fileCount = $('#files').find('tr').length;
$('#fileName').html('共上传 ' + fileCount + ' 个文件');
art.dialog.data(pageType + "_attachment",saveFile);
});
/** 删除已上传的文件*/
$('#existingFiles').on('click','.deleteExisting',function (e) {
var id = e.target.parentNode.parentNode.children[0].id
$.pikaQajax({
url: "/company-check/delete-attachment?id=" + id,
type: "post",
success: function (data) {
if (data.status === 200) {
e.target.parentNode.parentNode.remove();
var fileCount = $('#files').find('tr').length;
$('#fileName').html('共上传 ' + fileCount + ' 个文件');
}else {
$.alert(data.msg);
}
}
});
});
/** 下载主表附件*/
$('#existingFiles').on('click','.downloadExisting',function (e) {
var id = e.target.parentNode.parentNode.children[0].id
$.pikaQajax({
url: "/company-check/down-file",
data: {"id": id},
type: "post",
dataType: "json",
success: function (data) {
if (data.status === 200) {
var filePath = data.msg;
if(filePath.indexOf("D:\\temp_file\\") >= 0 ) {
filePath = filePath.substring(13,filePath.length)
}
window.open(filePath);
}else {
$.alert(data.msg);
}
},
error:function (data) {
$.alert("操作失败,"+ data.msg);
}
})
});
// $("#fileUpload").on('click',function () {
// var len = formData.getAll('UploadForm[Files][]').length;
// $("#overlay").show();
// if(len > 1){
// var deleteBtn = $(".delete");
// //通过ajax进行上传
// $.ajax({
// url: '/finalize/upload',
// type: 'POST',
// cache: false,
// data: formData,
// processData: false,
// contentType: false
// }).done(function(res) {
// if(res.code == 'ok'){
// //进度条设置
// var value = 0;
// var timer2 = setInterval(function () {
// value ++;
// $("#progress").css('width', value + "%");
// if (value == 120) {
// clearInterval(timer2);
// $("#overlay").hide();
// alert("文件上传成功!");
// }
// }, 50);
// //删除对应按钮
// $("#fileUpload").css("display","none");
// $.each(deleteBtn,function (index, item) {
// $(item).css("display","none");
// });
// $('#files').append('<tr><td><td><td><a type="button" class="btn btn-success pull-right" id="fileDown" href="/finalize/get-file?id=' + res.data.id + '" >文件下载</a></td></tr>')
// }
//
// }).fail(function(res) {
// alert("文件上传失败:" + res.msg);
// });
// }else {
// alert("请选择需要上传的文件!");
// }
//
// });
这里的上传我用不到,代码隐藏掉了。我是在一个子弹出层上传完文件后,关闭后,再父弹出层上进行保存,所有的文本信息和文件,一起提交到后端处理,保存。
文件是通过fastdfs上传到服务器,现在要支持下载,写一个后端支持下载的功能,期间碰到跨域的问题,前端无法访问跨域的文件地址,试了其他方法,有很多可以解决的办法,下面是我的写法,前端可以访问,并展示的虚拟资源路径。
/**
* 下载
*/
@RequestMapping("/down-file")
@ResponseBody
public ApiResponses<Void> getDownUrl(String id, HttpServletResponse res){
UploadFileDTO uploadFileDTO = uploadFileRpcService.getFileById(id);
if (StringUtils.isBlank(uploadFileDTO.getFilePath())){
return ApiResponses.failure(new ErrorCode("文件URL路径不存在!",500,true,"文件URL路径不存在"));
}
String netPath = storageUrl + uploadFileDTO.getFilePath();
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
File file = null;
//删除之前的临时文件
FileUtils.deleteDirectory("D:/temp_file");
try {
URL url = new URL(netPath);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
InputStream is = connection.getInputStream();
bis = new BufferedInputStream(is);
file = new File("D:/temp_file");
if(!file.exists()){//如果文件夹不存在
file.mkdir();//创建文件夹
}
file = new File("D:/temp_file/" + uploadFileDTO.getFileName());//获取文件名
FileOutputStream fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
int b = 0;
byte[] byArr = new byte[1024*4];
while((b=bis.read(byArr))!=-1){
bos.write(byArr, 0, b);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(bis!=null){
bis.close();
}
if(bos!=null){
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return success( file.getPath());
}
上面的下载方法适合widows部署环境,如果是linux环境的话,上面的下载方法不能用。
linux 环境的换成下面写法:
/**
* 下载
*/
@RequestMapping("/down-file")
public void getDownUrl(String id, HttpServletResponse res) throws IOException, MyException {
UploadFileDTO uploadFileDTO = uploadFileRpcService.getFileById(id);
if (StringUtils.isBlank(uploadFileDTO.getFilePath())){
return ;
}
String netPath = storageUrl + uploadFileDTO.getFilePath();
//取出正数第三个“/”后面的内容
String[] split = netPath.split("\\/", 4);//分4部分,第一部分为http: 第二部分为空格 第三部分为ip和端口 第四部分为其他
String fileId = split[3];
byte[] download = fastDFSUtils.downloadByFileId(fileId);
OutputStream os = response.getOutputStream();
// 设置响应头
// 文件编码 处理文件名中的 '+'、' ' 特殊字符
String encoderName = URLEncoder.encode(uploadFileDTO.getFileName(), "UTF-8").replace("+", "%20").replace("%2B", "+");
response.setHeader("Content-Disposition", "attachment;filename=\"" + encoderName + "\"");
response.setContentType("multipart/form-data" + ";charset=UTF-8");//设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setHeader("Accept-Ranges", "bytes");
ByteArrayInputStream is = new ByteArrayInputStream(download);
byte[] buffer = new byte[1024 * 5];
int len = 0;
while ((len = is.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
os.flush();
}
前端用a标签下载
<a href="javascript:void(0)" th:href="'/company-check/down-file?id='+${item.getTranLicFileId()}"><i class="fa fa-download ui-datepicker-trigger" style="top: 10px;"></i></a>
附上fastDFs工具类
import lombok.extern.slf4j.Slf4j;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Slf4j
@Component
public class FastDfsUtil {
@Value("${fastdfs.storage_servers}")
private String storageUrl;
@Value("${spring.profiles.active}")
private String propertyType;
/**
* 根据fileId从trackerServer获取可用storageServer并返回字节数组
*
* @param fileId
* @return
* @throws IOException
* @throws MyException
*/
public byte[] downloadByFileId(String fileId) throws IOException, MyException {
ClientGlobal.initByProperties(getFastDfsProperties());
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = null;
try {
trackerServer = tracker.getConnection();
StorageServer storageServer = null;
StorageClient1 client = new StorageClient1(trackerServer, storageServer);
byte[] re = client.download_file1(fileId);
return re;
} catch (IOException | MyException e) {
throw e;
} finally {
trackerServer.close();
}
}
/**
* 根据fileId从trackerServer获取可用storageServer并返回字节数组
*
* @param fileId
* @return
* @throws IOException
* @throws MyException
*/
public byte[] getFileList(String fileId) throws IOException, MyException {
ClientGlobal.initByProperties(getFastDfsProperties());
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = null;
try {
trackerServer = tracker.getConnection();
StorageServer storageServer = null;
StorageClient1 client = new StorageClient1(trackerServer, storageServer);
byte[] re = client.download_file1(fileId);
return re;
} catch (IOException | MyException e) {
throw e;
} finally {
trackerServer.close();
}
}
/**
* fastdfs文件上传
*
* @param file 属于MultipartFile类型
* @return
* @throws IOException
* @throws MyException
*/
public String fileUpload(MultipartFile file) throws IOException, MyException {
if (file.isEmpty()) {
return null;
} else {
String tempFileName = file.getOriginalFilename();
//fastDFS方式
ClientGlobal.initByProperties(getFastDfsProperties());
byte[] fileBuff = file.getBytes();
String fileId = "";
String fileExtName = tempFileName.substring(tempFileName.lastIndexOf(".") + 1);
//建立连接
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getConnection();
StorageClient1 client = new StorageClient1(trackerServer, null);
//设置元信息
NameValuePair[] metaList = new NameValuePair[3];
metaList[0] = new NameValuePair("fileName", tempFileName);
metaList[1] = new NameValuePair("fileExtName", fileExtName);
metaList[2] = new NameValuePair("fileLength", String.valueOf(file.getSize()));
//上传文件,获得fileId
fileId = client.upload_file1(fileBuff, fileExtName, metaList);
return fileId;
}
}
/**
* 获取FastDfs配置
*/
private String getFastDfsProperties() {
String CLASS_PATH = "";
ApplicationHome home = new ApplicationHome();
File file = home.getSource();
if(file != null && file.exists()){ //外部配置
CLASS_PATH = file.getParentFile().getPath() + File.separator + "config" + File.separator;
// log.info("外部配置:" + CLASS_PATH + "application-" + propertyType + ".properties");
return CLASS_PATH + "application-" + propertyType + ".properties";
}else{
// log.info("外部配置为空" + "application-" + propertyType + ".properties");
return "application-" + propertyType + ".properties";
}
}
}