MetaFile
这个将file进行封装,将InputStream 等一系列封装成属性,并对外提供一系列方法。
public class MetaFile {
public final static String ROOT_PATH = "/usr/hrfiles/recruitmentZip/";
private File file;
private String fileName;
private String simpleName;
private InputStream inputStream;
private OutputStream outputStream;
private Long size;
private Type type;
private final static String uuid = UUID.randomUUID().toString();
enum Type{
IMAGE("img"),
TXT("txt"),
XLSX("xlsx"),
XLS("xls");
private Type(String sufix){
this.sufix = sufix;
}
private String sufix;
public String getSufix() {
return sufix;
}
public void setSufix(String sufix) {
this.sufix = sufix;
}
public static Type getType(String str){
if(str.indexOf(".") != -1){
String[] s = str.split("\\.");
return getType(s[s.length-1]);
}
switch (str){
case "jpg":
case "png":
case "jepg":
case "gif": return IMAGE;
case "txt": return TXT;
case "xlsx": return XLSX;
case "xls": return XLS;
default: return null;
}
}
}
public MetaFile(MultipartFile multipartFile) {
parse(transferToFile(multipartFile));
}
public MetaFile(String fileName){
this(new File(fileName),null);
}
public MetaFile(File file){
this(file,null);
}
public MetaFile(String path, String fileName){
this(new File(path+fileName),path);
}
public MetaFile(File file, String path){
if(path != null && !path.isEmpty()) {
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
}
if(file.exists() && file.isDirectory()){
throw new RuntimeException("error init MateFile, File allready exists or File is a Directory!");
}
parse(file);
}
private void parse(File file) {
this.file = file;
this.fileName = file.getName();
this.simpleName = file.getName().substring(0,file.getName().lastIndexOf("."));
this.size = file.length();
this.type = Type.getType(this.fileName);
try{
if(!file.exists()) {
file.createNewFile();
}
this.inputStream = new FileInputStream(file);
//如果不加第二个参数会把源文件清空成0字节
this.outputStream = new FileOutputStream(file,true);
}catch (Exception e){
throw new RuntimeException("error init MateFile, The Stream get ERROR!");
}
}
public void renameTo(File dest){
file.renameTo(dest);
}
public void download(String path,String fileFullname) throws IOException{
if(StringUtils.isEmpty(path) || StringUtils.isEmpty(fileFullname)){
log.error("the path or fileFullname cant be empty!");
return;
}
if(!Pattern.matches("^([a-zA-Z0-9]){1,}\\.([a-zA-Z0-9]{1,})$", fileFullname)){
log.error("the fileFullname may be not xx.xx format!");
return;
}
String descFileName = fileFullname.split(".")[0];
String suffix = fileFullname.split(".")[1];
//目标文件(下载文件路径及名称)
File descFile = new File(path+"//"+fileFullname);
if(descFile.exists()){
descFile = new File(path+"//"+descFileName+uuid+"."+suffix);
}
outputStream = new BufferedOutputStream(new FileOutputStream(descFile));
download(outputStream);
}
public void download(OutputStream outputStream) throws IOException{
int n;
byte[] buffer = new byte[1024];
BufferedInputStream bis = new BufferedInputStream(inputStream);
while((n=bis.read(buffer)) != -1){
outputStream.write(buffer,0,n);//每次保证只写入读到的流位置
}
outputStream.flush();
this.colse();
}
public File addByte(byte[] b) {
try {
outputStream.write(b);
} catch (IOException e) {
log.error(e.getMessage());
}finally {
colse();
}
return file;
}
public void finish(){
if(file != null){
file.delete();
}
colse();
}
private void colse(){
try {
if(inputStream != null){
inputStream.close();
}
if(outputStream != null) {
outputStream.close();
}
}catch (IOException e){
log.error("close Stream error!");
}
}
private File transferToFile(MultipartFile multipartFile) {
// 选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
File file = null;
try {
String originalFilename = multipartFile.getOriginalFilename();
String[] filename = originalFilename.split("\\.");
file=File.createTempFile(filename[0], "."+filename[1]);
multipartFile.transferTo(file);
file.deleteOnExit();
} catch (IOException e) {
log.error("multipartFile to file error!");
}
return file;
}
public static void main(String[] args) throws IOException {
// System.outputStream.println(Pattern.matches("^([a-zA-Z0-9]){1,}\\.([a-zA-Z0-9]{1,})$", "a.a0"));
MetaFile file = new MetaFile("H://加班申请单(国庆假期)..xlsx");
System.out.println(file.type);
}
}
MetaResponse
这个是对HttpServletResponse的一个封装。其中会配合MetaFile 以及前面设计的ExcelUtils对外提供下载方法。
public class MetaResponse {
private HttpServletResponse response;
private MetaFile metaFile;
private OutputStream outputStream;
private String contentType;
private Integer contentLength;
private Map<String,String> header;
public MetaResponse(ServletResponse response){
this(response,null,null,null);
}
public MetaResponse(ServletResponse response,Integer contentLength,Map<String,String> header){
this(response,null,contentLength,header);
}
public MetaResponse(ServletResponse response,String contentType,Integer contentLength,Map<String,String> header){
this.response = (HttpServletResponse)response;
this.contentType = contentType;
this.header = header;
this.contentLength = contentLength;
try {
this.outputStream = response.getOutputStream();
} catch (IOException e) {
log.error("init MetaResponse error!");
}
init();
}
public void init(){
this.response.setContentType(contentType);
if(contentLength != null && contentLength > 0)
this.response.setContentLength(contentLength);
if(header != null) {
header.entrySet().forEach(entry -> {
this.response.setHeader(entry.getKey(), entry.getValue());
});
}
}
public void downloadExcel(List list,LinkedHashMap header){
downloadExcel(list,header, "sheet1","file"+new Date().getTime());
}
public void downloadExcel(List list, LinkedHashMap header, String fileName){
downloadExcel(list,header, "sheet1",fileName);
}
public void downloadExcel(List list,LinkedHashMap header,String sheetName,String fileName){
try{
Workbook workbook = ExcelUtils.exportXlsx(sheetName, list, header);
response.setContentType("application/binary;charset=ISO8859_1");
String fn = new String(fileName.getBytes(), "ISO8859_1");
response.setHeader("Content-disposition", "attachment; filename=" + fn + ".xlsx");
workbook.write(outputStream);
}catch (Exception e){
throw new BaseException(ResultCode.ERROR);
}finally {
close();
}
}
public void download(File file) throws IOException {
this.download(file,true);
}
public void download(File file,boolean close) throws IOException {
this.download(file,close,false);
}
public void download(File file,boolean close,boolean delete) throws IOException {
metaFile = new MetaFile(file);
response.setHeader("Content-disposition","attachment;filename=" +
URLEncoder.encode(metaFile.getFileName(),"UTF-8"));
if(this.response.getContentType() == null || this.response.getContentType().isEmpty()){
this.response.setContentType("multipart/form-data");
}
metaFile.download(outputStream);
if(close){
close();
}
if(delete) {
deleteFile(file);
}
}
//定义一个方法好看点
private void deleteFile(File file){
file.delete();
}
private void close(){
if(outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
throw new BaseException(ResultCode.ERROR);
}
}
}
}
使用
Export Header
只需要定义Exprt Header 然后给出需要导出的数据List即可。