文件sql:
CREATE TABLE `document_file` (
`id` int NOT NULL AUTO_INCREMENT,
`bussiness_id` varchar(168) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '业务id',
`domain` varchar(200) DEFAULT '' COMMENT '主目录',
`file_name` varchar(200) DEFAULT '' COMMENT '原文件名',
`file_suffix` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '文件后缀',
`name` varchar(100) DEFAULT '' COMMENT '系统文件名',
`path` varchar(100) DEFAULT '' COMMENT '路径',
`path_ext` varchar(100) DEFAULT '' COMMENT '扩展目录',
`size` bigint DEFAULT '0' COMMENT '文件大小',
`delete_flg` tinyint DEFAULT '0' COMMENT '删除标记 0 未删除 1 删除',
`create_user_id` int DEFAULT '0' COMMENT '创建人id',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`,`bussiness_id`) USING BTREE,
KEY `del_code` (`delete_flg`,`bussiness_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb3 COMMENT='文档文件';
实体类:
import lombok.*;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table(name = "document_file")
public class Attachment implements Serializable {
private static final long serialVersionUID = 6295975348974510001L;
@Id
@KeySql(useGeneratedKeys = true)
private Integer id;
// 业务id
@Column(name = "bussiness_id")
private String bussinessId;
// 主目录
@Column(name = "domain")
private String domain;
// 原文件名
@Column(name = "file_name")
private String fileName;
// 系统文件名
@Column(name = "name")
private String name;
// 文件名后缀
@Column(name = "file_suffix")
private String fileSuffix;
// 路径
@Column(name = "path")
private String path;
// 扩展目录
@Column(name = "path_ext")
private String pathExt;
// 文件大小
@Column(name = "size")
private Long size;
// 是否删除
@Column(name = "delete_flg")
private Integer deleteFlg;
// 创建人id
@Column(name = "create_user_id")
private Integer createUserId;
// 创建时间
@Column(name = "create_time")
private String createTime;
}
先来2个参数:
String PATH = "img/st/";
String LOCAL_HOST = "http://localhost:8888/";
上传文件的service层:
// 上传附件
public Integer uploadFile(MultipartFile multipartFile, String bussinessId, Op op) throws IOException {
String LOCAL_HOST = sysConfigService.getValueByKey(CacheKeyConstant.LOCAL_HOST);
String uuid = UUID.randomUUID().toString();
if(StrUtil.isBlank(bussinessId)){
bussinessId = uuid;
}
Assert.isTrue(!multipartFile.isEmpty(),"上传文件为空");
Attachment uploadFile = new Attachment();
// 保存原文件名称,文件列表展示需要用到
String fileName = multipartFile.getOriginalFilename();
uploadFile.setFileName(fileName);
// 生成系统文件名称,不可重复,防止同名文件上传覆盖问题
String fileSuffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".")).toLowerCase();
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
// 判定传递的类型
Assert.isTrue(isUploadType(fileType),"目前只支持:"bmp", "jpg", "jpeg", "png", "gif"");
String name = bussinessId + DateUtil.format(new Date(), "yyyyMMddHHmmss");
uploadFile.setName(name);
uploadFile.setFileSuffix(fileSuffix);
// 判断文件类型
uploadFile.setDomain(LOCAL_HOST + PATH);
//这种方式比类型强转效率更高
String pathExt = System.currentTimeMillis()+"";
uploadFile.setPath(LOCAL_HOST + PATH + pathExt);
uploadFile.setPathExt(pathExt);
// 获取文件大小
uploadFile.setSize(multipartFile.getSize());
uploadFile.setBussinessId(bussinessId);
uploadFile.setCreateTime(DateUtil.now());
uploadFile.setDeleteFlg(DataConstant.DELETE_FLAG);
uploadFile.setCreateUserId(op.getOpUserId());
// 将文件保存到本目录/resources/files/下
// DateUtil.today()得到得是当天日期如:20230715,这个会在/resources/files/下再以日期生成一层目录
String filePath = Paths.get("").toAbsolutePath().normalize().toString(); // 获取当前JAR文件所在目录的绝对路径
File newFile = new File(filePath + "/" + PATH + pathExt + "/" + name + fileSuffix);
// 保证这个文件的父文件夹必须要存在
if (!newFile.getParentFile().exists()) {
newFile.getParentFile().mkdirs();
}
newFile.createNewFile();
// 将文件内容写入到这个文件中
InputStream is = multipartFile.getInputStream();
FileOutputStream fos = new FileOutputStream(newFile);
try {
int len;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
}catch (Exception e){
return -1;
}finally {
// 关流顺序,先打开的后关闭
fos.close();
is.close();
}
attachmentDao.insert(uploadFile);
return uploadFile.getId();
}
public boolean isUploadType(String fileType){
String img[] = {"bmp", "jpg", "jpeg", "png", "gif"};
for (int i = 0; i < img.length; i++) {
if(img[i].equals(fileType)) return true;
}
return false;
}
下载文件的service:
public void showPhoto(HttpServletResponse response, Integer id){
Attachment attachment = Attachment.builder().build();
if(id != null){
attachment = attachmentDao.selectByPrimaryKey(id);
}
String filePath = Paths.get("").toAbsolutePath().normalize().toString(); // 获取当前JAR文件所在目录的绝对路径
String showPath = filePath + "/" + PATH + attachment.getPathExt() + "/" + attachment.getName()
+ attachment.getFileSuffix();
// 去./resources/files/目录下取出文件
log.error("showPathshowPathshowPathshowPathshowPath=" + showPath);
File downloadFile = new File(showPath);
Assert.isTrue(downloadFile.exists(),"查询文件为空");
Assert.isTrue(downloadFile.length() != 0,"文件没东西");
InputStream is = null;
OutputStream os = null;
try {
// 判断是否是图片,如果是图片加上 response.setContentType("image/jpeg"),这样就可以直接在浏览器打开而不是下载
response.setContentType("image/jpeg");
response.addHeader("Content-Length", "" + downloadFile.length());
is = new FileInputStream(downloadFile);
os = response.getOutputStream();
IOUtils.copy(is, os);
} catch (Exception e) {
log.error("展示图片发生异常", e);
} finally {
try {
if (os != null) {
os.flush();
os.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
log.error("关闭流发生异常", e);
}
}
}
web层
// 上传
public Integer uploadFile(@RequestPart("file") MultipartFile file,
@RequestParam(required = false) String bussinessId) throws IOException {
Op op = Op.createOp(TokenCache.getInstance().get());
return attachmentService.uploadFile(file, bussinessId,op);
}
// 展示
public void showPhoto(HttpServletResponse response,
@RequestParam(required = false) Integer id) throws Exception {
Assert.isTrue(id != null ,"必须传递一个");
attachmentService.showPhoto(response, id);
}
获取jar内的文件:
InputStream inputStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("img/st/.....xlsx");
//拿到项目的文件,转换成文件输入流
ClassPathResource resource = new ClassPathResource("\\templates\\contract-template.ftl");
//获取文件输入流
InputStream stream = resource.getInputStream();