文件上传
SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
@PostMapping("/import")
public String importData(MultipartFile file, HttpServletRequest req) throws IOException {
String format = sdf.format(new Date());
String realPath = req.getServletContext().getRealPath("/upload") + format;
File folder = new File(realPath);
if (!folder.exists()) {
folder.mkdirs();
}
String oldName = file.getOriginalFilename();
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
file.transferTo(new File(folder,newName));
String url = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/upload" + format + newName;
System.out.println(url);
return "success";
}
这里的文件上传比较简单,上传的文件按照日期进行归类,使用 UUID 给文件重命名。为了简化代码,省略掉了异常捕获,上传结果直接返回成功,后端代码大伙可根据自己的实际情况自行修改。
Ajax上传
<body>
<div id="result"></div>
<input type="file" id="file">
<input type="button" onclick="uploadData()" value="提交">
</body>
<script>
function uploadData() {
//单文件上传
var file = $("#file")[0].files[0];
var formData = new FormData();
formData.append("file", file);
$.ajax({
type: "post",
url: "/upload",
processData: false,
contentType: false,
data: formData,
success:function (res) {
$("#result").html(res);
}
})
}
</script>
processData
默认值: true。默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 “application/x-www-form-urlencoded”。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。
单文件下载
/**
* 单文件下载
* @param id 文件id
* @param filePath 文件路径 d:\\uploadPath\\1.xls
* @param response
*/
public void download(String id, String filePath, HttpServletResponse response, HttpServletRequest request) {
try {
if (StringUtils.isEmpty(filePath)){
//根据文件id获取到文件路径
SysFile sysFile = sysFileService.get(id);
filePath = sysFile.getFilePath;
}
File file = new File(filePath);
//得到文件名
String fileName = filePath.substring(filePath.lastIndexOf(File.separator)+1);
//把文件名按UTF-8取出并按ISO8859-1编码,保证弹出窗口中的文件名中文不乱码,中文不要太多,最多支持17个中文,因为header有150个字节限制。
fileName = new String(fileName.getBytes("UTF-8"),"ISO8859-1");
//告诉浏览器输出内容为流
response.setContentType("application/octet-stream");
//设置弹出的下载对话框中的文件类型图片是按照文件的扩展名显示的,点保存后,文件以filename的值命名,保存类型以Content中设置的为准。
//注意:在设置Content-Disposition头字段之前,一定要设置Content-Type头字段。
response.addHeader("Content-Disposition", "attachment;filename="+fileName);
String len = String.valueOf(file.length());
//设置内容长度
response.setHeader("Content-Length", len);
OutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(file);
byte[] b = new byte[1024];
int n;
while((n=in.read(b))!=-1){
out.write(b, 0, n);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
多文件下载
/**
* 多文件压缩下载
* @param ids 文件id集合
*/
public void downloadAllFiles(String ids, HttpServletResponse response, HttpServletRequest request) {
// 1、根据ids查询下载的文件地址列表
if (StringUtils.isEmpty(ids)) {
return ;
}
String filePath = "", realFileName = "";
if (ids.contains(SeparatorEnum.COMMA.getValue())) {
// 为了保留原始的文件名称,将文件集合设置成map类型,key值是原始文件名
Map<String, File> fileMap = new HashMap<>();
String[] fileIds = ids.split(SeparatorEnum.COMMA.getValue());
for (String fileId : fileIds) {
if (StringUtils.isNotEmpty(fileId)) {
// 2、将文件放入集合中
File file = new File(filePath);
if (!file.exists()) {
try {
throw new FileNotFoundException(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
fileMap.put(realFileName, file);
}
}
// 3、响应头的设置
String downloadName = UUID.randomUUID().toString().replaceAll("-", "") + ".zip";
CompressDownloadUtils.setDownloadResponse(request, response, downloadName);
// 4、多个文件压缩写进响应的输出流
try {
CompressDownloadUtils.compressZip(fileMap, response.getOutputStream());
} catch (IOException e) {
log.error("下载文件失败", e);
}
} else {
// 单文件下载
download(ids, "", response, request);
}
}
压缩下载工具类
public class CompressDownloadUtils {
private static final Logger log = LoggerFactory.getLogger(CompressDownloadUtils.class);
private CompressDownloadUtils() {
}
/**
* 设置下载响应头
*
* @param response
* @return
* @date 2021-02-08
*/
public static HttpServletResponse setDownloadResponse(HttpServletRequest request, HttpServletResponse response, String downloadName) {
response.reset();
response.setCharacterEncoding(FileUtils.getBrowserCharset(request));
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;fileName*=UTF-8''" + downloadName);
return response;
}
/**
* 字符串转换为整型数组
*
* @param param
* @return
* @date 2021-02-08
*/
public static Integer[] toIntegerArray(String param) {
return Arrays.stream(param.split(","))
.map(Integer::valueOf)
.toArray(Integer[]::new);
}
/**
* 将多个文件压缩到指定输出流中
*
* @param files 需要压缩的文件列表
* @param outputStream 压缩到指定的输出流
* @date 2021-02-08
*/
public static void compressZip(List<File> files, OutputStream outputStream) {
ZipOutputStream zipOutStream = null;
try {
// 包装成ZIP格式输出流
zipOutStream = new ZipOutputStream(new BufferedOutputStream(outputStream));
// 设置压缩方法
zipOutStream.setMethod(ZipOutputStream.DEFLATED);
// 将多文件循环写入压缩包
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
FileInputStream filenputStream = new FileInputStream(file);
byte[] data = new byte[(int) file.length()];
filenputStream.read(data);
// 添加ZipEntry,并ZipEntry中写入文件流,这里,加上i是防止要下载的文件有重名的导致下载失败
zipOutStream.putNextEntry(new ZipEntry(i + file.getName()));
zipOutStream.write(data);
filenputStream.close();
zipOutStream.closeEntry();
}
} catch (IOException e) {
log.error("文件压缩失败", e);
} finally {
try {
if (Objects.nonNull(zipOutStream)) {
zipOutStream.flush();
zipOutStream.close();
}
if (Objects.nonNull(outputStream)) {
outputStream.close();
}
} catch (IOException e) {
log.error("文件压缩失败", e);
}
}
}
/**
* 将多个文件压缩到指定输出流中(不用file中的文件名,Map的key为文件名)
*
* @param files 需要压缩的文件列表
* @param outputStream 压缩到指定的输出流
* @date 2021-02-08
*/
public static void compressZip(Map<String, File> files, OutputStream outputStream) {
ZipOutputStream zipOutStream = null;
try {
// 包装成ZIP格式输出流
zipOutStream = new ZipOutputStream(new BufferedOutputStream(outputStream));
// 设置压缩方法
zipOutStream.setMethod(ZipOutputStream.DEFLATED);
// 将多文件循环写入压缩包
int i = 1;
for (Map.Entry<String, File> entry : files.entrySet()) {
String fileName = entry.getKey();
File file = entry.getValue();
FileInputStream filenputStream = new FileInputStream(file);
byte[] data = new byte[(int) file.length()];
filenputStream.read(data);
//-- 添加ZipEntry,并ZipEntry中写入文件流,这里,加上i是防止要下载的文件有重名的导致下载失败
zipOutStream.putNextEntry(new ZipEntry(i + fileName));
zipOutStream.write(data);
filenputStream.close();
zipOutStream.closeEntry();
i++;
}
} catch (IOException e) {
log.error("文件压缩失败", e);
} finally {
try {
if (Objects.nonNull(zipOutStream)) {
zipOutStream.flush();
zipOutStream.close();
}
if (Objects.nonNull(outputStream)) {
outputStream.close();
}
} catch (IOException e) {
log.error("文件压缩失败", e);
}
}
}
/**
* 下载文件
*
* @param outputStream 下载输出流
* @param zipFilePath 需要下载文件的路径
* @date 2021-02-08
*/
public static void downloadFile(OutputStream outputStream, String zipFilePath) {
File zipFile = new File(zipFilePath);
if (!zipFile.exists()) {
// 需要下载压塑包文件不存在
return;
}
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(zipFile);
byte[] data = new byte[(int) zipFile.length()];
inputStream.read(data);
outputStream.write(data);
outputStream.flush();
} catch (IOException e) {
log.error("下载文件失败", e);
} finally {
try {
if (Objects.nonNull(inputStream)) {
inputStream.close();
}
if (Objects.nonNull(outputStream)) {
outputStream.close();
}
} catch (IOException e) {
log.error("下载文件失败", e);
}
}
}
/**
* 删除指定路径的文件
*
* @param filepath
* @date 2021-02-08
*/
public static void deleteFile(String filepath) {
File file = new File(filepath);
deleteFile(file);
}
/**
* 删除指定文件
*
* @param file
* @date 2021-02-08
*/
public static void deleteFile(File file) {
// 路径为文件且不为空则进行删除
if (file.isFile() && file.exists()) {
file.delete();
}
}
}