文件操作工具类

package com.jxdinfo.hussar.utils;

import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.baomidou.mybatisplus.toolkit.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 文件上传工具类
 *
 * @author 
 */
public class FileUtils {
    // 分隔符 可以用来在存储数据时分隔多个文件名
    public static final String SEPARATOR = "&&";

    /**
     * 获取路径指向的文件
     * 如果是文件则返回文件对象 否则返回null
     *
     * @param path
     * @return
     */
    public static File getFile(String path) {
        // 检查文件是否存在
        File file = new File(path);
        if (!file.exists()) {
            System.out.println("文件不存在:" + path);
            return null;
        }
        if (!file.isFile()) {
            System.out.println("文件路径有错误:" + path);
            return null;
        }
        return file;
    }

    /**
     * 文件上传方法
     * 返回的JSONArray中每一个接收到的文件信息构成一个JSONObject 用key从中取出文件信息
     *
     * @param filePath 文件存放路径
     * @param request  页面上传请求
     */
    public static List<FileInfo> fileUpload(String filePath, HttpServletRequest request) throws IOException {
        // 映射集
        List<FileInfo> fileInfoList = new ArrayList<>();
        // 设置编码
        request.setCharacterEncoding("UTF-8");
        // 解析请求
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        // 文件上传
        MultipartFile multipartFile = null;
        Map map = multipartRequest.getFileMap();
        for (Iterator i = map.keySet().iterator(); i.hasNext(); ) {
            Object obj = i.next();
            multipartFile = (MultipartFile) map.get(obj);
            if (null != multipartFile) {
                String fileName = multipartFile.getOriginalFilename();
                //处理ie浏览器filename包含盘符的问题
                String agent = request.getHeader("User-Agent"); //获取浏览器
                if (agent.contains("MSIE") || agent.contains("Trident") || agent.contains("Edge")) {
                    fileName = fileName.substring(fileName.lastIndexOf('\\') + 1);
                }
                // 获取文件后缀(含.)
                String postfix = fileName.substring(fileName.lastIndexOf("."));
                // 随机生成上传目录中的文件名称
                String id = IdWorker.get32UUID();
                try {
                    // 检查文件存放路径对应文件夹是否存在
                    File dir = new File(filePath);
                    if (!dir.exists()) {
                        // 不存在则创建
                        dir.mkdirs();
                    }
                    String fileSavePath = filePath + id + postfix;
                    // 存储
                    multipartFile.transferTo(new File(fileSavePath));
                    // 整理对应
                    FileInfo fileInfo = new FileInfo();
                    fileInfo.setFileName(fileName);
                    fileInfo.setFilePath(filePath);
                    long size = multipartFile.getSize();
                    fileInfo.setFileSize(size);
                    fileInfo.setPostfix(postfix);
                    fileInfo.setUploadTime(new Date());
                    fileInfo.setFileSavePath(fileSavePath);
                    fileInfo.setFileId(id);
                    fileInfoList.add(fileInfo);
                } catch (IOException e) {
                    throw new HussarException(BizExceptionEnum.UPLOAD_ERROR);
                }
            }
        }
        return fileInfoList;
    }

    /**
     * 文件上传方法 指定保存路径
     * 每一个接收到的文件信息构成返回的List中的一个FileInfo对象,获取其属性可从中取出文件信息
     *
     * @param fileUrl 文件保存路径
     * @param request 页面上传请求
     * @return
     * @throws IOException
     */
    public static List<FileInfo> fileUploadToUrl(String fileUrl, HttpServletRequest request) throws IOException {
        // 映射集
        List<FileInfo> fileInfoList = new ArrayList<>();
        // 设置编码
        request.setCharacterEncoding("UTF-8");
        // 解析请求
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        // 文件上传
        MultipartFile multipartFile = null;
        Map map = multipartRequest.getFileMap();
        for (Iterator i = map.keySet().iterator(); i.hasNext(); ) {
            Object obj = i.next();
            multipartFile = (MultipartFile) map.get(obj);
            if (null != multipartFile) {
                String fileName = multipartFile.getOriginalFilename();
                // 获取文件后缀
                String postfix = fileUrl.substring(fileUrl.lastIndexOf("."));
                // 获取最后一个分隔符位置
                int index = fileUrl.lastIndexOf("\\");
                if (index == -1) {
                    index = fileUrl.lastIndexOf("/");
                }
                // 获取文件ID
                String id = fileUrl.substring(index + 1, fileUrl.lastIndexOf("."));
                // 获取文件存储路径
                String filePath = fileUrl.substring(0, index + 1);
                try {
                    // 删除该位置的旧文件
                    fileDelete(fileUrl);
                    // 存储
                    multipartFile.transferTo(new File(fileUrl));
                    // 整理对应
                    FileInfo fileInfo = new FileInfo();
                    fileInfo.setFileName(fileName);
                    fileInfo.setFilePath(filePath);
                    long size = multipartFile.getSize();
                    fileInfo.setFileSize(size);
                    fileInfo.setPostfix(postfix);
                    fileInfo.setUploadTime(new Date());
                    fileInfo.setFileSavePath(fileUrl);
                    fileInfo.setFileId(id);
                    fileInfoList.add(fileInfo);
                } catch (IOException e) {
                    throw new HussarException(BizExceptionEnum.UPLOAD_ERROR);
                }
            }
        }
        return fileInfoList;
    }

    /**
     * 文件删除方法
     *
     * @param path 文件的完整路径
     * @return
     */
    public static boolean fileDelete(String path) {
        if (StringUtils.isEmpty(path)) {
            return true;
        }
        File file = new File(path);
        if (file.exists() && file.isFile()) {
            return file.delete();
        } else {
            // 文件不存在
            return false;
        }
    }

    /**
     * 文件夹删除方法
     *
     * @param path
     * @return
     */
    public static boolean directoryDelete(String path) {
        // 如果path不以文件分隔符结尾 自动添加文件分隔符
        if (!path.endsWith(File.separator))
            path = path + File.separator;
        File dirFile = new File(path);
        // 如果目录不存在或者不是一个目录 则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            return false;
        }
        // 是否完全删除成功的标识
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        if (files != null) {
            for (File file : files) {
                // 删除子文件
                if (file.isFile()) {
                    flag = fileDelete(file.getAbsolutePath());
                    if (!flag)
                        break;
                }
                // 删除子目录
                else if (file.isDirectory()) {
                    flag = directoryDelete(file
                            .getAbsolutePath());
                    if (!flag)
                        break;
                }
            }
        }
        // 如果目录下的文件或文件夹没有删除成功则返回失败
        if (!flag) {
            return false;
        }
        // 目录下文件全部清空之后 删除目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }

    public static boolean download(String path, String fileName, HttpServletResponse response) {
        // 检查文件是否存在
        File file = FileUtils.getFile(path);
        if (file == null) {
            return false;
        }
        try {
            fileName = URLEncoder.encode(fileName, "UTF8");
            // 设置响应类型
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1"));
            response.addHeader("Content-Length", "" + file.length());
            response.setContentType("application/octet-stream");
            // 通过IO流传输数据
            InputStream input = new BufferedInputStream(new FileInputStream(path));
            OutputStream output = response.getOutputStream();
            byte[] buff = new byte[1024 * 100];// 缓冲区大小为100KB
            int len = 0;
            while ((len = input.read(buff)) > -1) {
                output.write(buff, 0, len);
            }
            //关闭输入输出流
            input.close();
            output.close();
            // 下载完成
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    //文件大小转换(B→KB、MB、GB,无法处理TB)
    public static String transformSize(String fileSize) {
        String result = "";
        if ("0".equals(fileSize)) {
            result = fileSize + "B";
        } else {
            BigDecimal dividend = new BigDecimal(fileSize);  //被除数
            BigDecimal value = new BigDecimal(1);

            BigDecimal divisorGB = new BigDecimal(1024 * 1024 * 1024);
            BigDecimal divisorMB = new BigDecimal(1024 * 1024);
            BigDecimal divisorKB = new BigDecimal(1024);
            BigDecimal divisorGBHalf = new BigDecimal(0.5 * 1024 * 1024 * 1024);
            BigDecimal divisorMBHALF = new BigDecimal(0.5 * 1024 * 1024);
            BigDecimal divisorKBHALF = new BigDecimal(0.5 * 1024);

            BigDecimal resultKB = dividend.divide(divisorKB, 2, RoundingMode.HALF_UP);  //KB,保留两位小数的除法
            BigDecimal resultMB = dividend.divide(divisorMB, 2, RoundingMode.HALF_UP);  //MB,保留两位小数的除法
            BigDecimal resultGB = dividend.divide(divisorGB, 2, RoundingMode.HALF_UP);  //GB,保留两位小数的除法

            // -1表示小于,0是等于,1是大于
            if (resultKB.compareTo(value) == -1 || resultKB.compareTo(value) == 0) {   //小于等于1KB
                if (dividend.compareTo(divisorKBHALF) == -1) {  //小于0.5KB
                    result = dividend.toString() + "B";
                } else {  //大于等于0.5KB,小于1KB
                    result = resultKB.toString() + "KB";
                }
            } else if (resultMB.compareTo(value) == -1 || resultMB.compareTo(value) == 0) { //大于1KB,小于等于1MB
                if (dividend.compareTo(divisorMBHALF) == -1) { //大于1KB,小于0.5MB(0.5*1024KB)
                    result = resultKB.toString() + "KB";
                } else {  //大于等于0.5MB,小于等于1MB
                    result = resultMB.toString() + "MB";
                }
            } else if (resultGB.compareTo(value) == -1 || resultGB.compareTo(value) == 0) { //大于1MB,小于等于1GB
                if (dividend.compareTo(divisorGBHalf) == -1) {  //大于1MB,小于0.5GB
                    result = resultMB.toString() + "MB";
                } else {  //大于等于0.5GB,小于等于1GB
                    result = resultGB.toString() + "GB";
                }
            } else {  //大于1GB
                result = resultGB.toString() + "GB";
            }
            //处理不是两位小数的格式
            String rightNum = result.substring(result.lastIndexOf(".") + 1, result.length() - 2); //小数点后的数字
            if (rightNum.length() > 2) {
                result = result.substring(0, result.lastIndexOf(".") + 2);
            }
            //处理(xx.x0+单位)的格式
            String wrongNum2 = result.substring(result.lastIndexOf(".") + 1, result.lastIndexOf(".") + 2);
            if ("0".equals(wrongNum2)) {
                result = result.substring(0, result.lastIndexOf(".") + 2) + result.substring(result.length() - 2, result.length());
            }
            //处理(xx.00+单位)的格式
            String wrongNum1 = result.substring(result.lastIndexOf(".") + 1, result.lastIndexOf(".") + 2);
            String numRight = result.substring(result.lastIndexOf(".") + 1);  //小数点后的字符串
            if ("0".equals(wrongNum1) && numRight.length() == 3) { //小数点后为(.0+单位的情形)
                result = result.substring(0, result.lastIndexOf(".")) + result.substring(result.length() - 2, result.length());
            }
        }
        return result;
    }

    // 时间戳转换为data格式字符串(xxxx年xx月xx日)
    public static String processTime(Date uploadTime) {
        String dateString = "";
        if (uploadTime != null) {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日");
            dateString = formatter.format(uploadTime);
        }
        return dateString;
    }

    // 根据上传地址,获取文件类型
    public static String getType(String appendixurl) {
        String type = "";
        if (appendixurl != null) {
            type = appendixurl.substring(appendixurl.lastIndexOf(".") + 1);
        }
        return type;
    }

    /**
     * 根据上传路径获取文件大小
     *
     * @param appendixurl 上传路径
     * @return
     */
    public static String getFileSize(String appendixurl) {
        String size = "";
        if (appendixurl != null) {
            File file = new File(appendixurl);
            if (file.exists() && file.isFile()) {
                //获取之后的文件大小单位为Byte(B)
                size = String.valueOf(file.length());
                //文件大小转换(B、KB、MB、GB、TB)
                size = transformSize(size);
            }
        }
        return size;
    }

    /**
     * 文件名导出时统一处理编码
     *
     * @param filename
     * @param request
     * @return
     * @throws IOException
     */
    public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
        String agent = request.getHeader("User-Agent"); //获取浏览器
        if (agent.contains("Firefox")) {
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?"
                    + base64Encoder.encode(filename.getBytes("utf-8"))
                    + "?=";
        } else if (agent.contains("MSIE") || agent.contains("Trident") || agent.contains("Edge")) {//"Trident", "Edge",ie浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        } else if (agent.contains("Safari")) {
            filename = new String(filename.getBytes("utf-8"), "ISO8859-1");
        } else {
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }

    /**
     * 将timestamp类型的值转换为string类型
     *
     * @param list
     * @param paramList
     */
    public static void trans2StringMapList(List<Map<String, Object>> list, List<Map<String, String>> paramList) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        ZoneId defaultZoneId = ZoneId.systemDefault();
        for (Map<String, Object> prjMap : list) {
            Map<String, String> paramMap = new HashMap<>();
            for (Map.Entry<String, Object> entry : prjMap.entrySet()) {
                if (Objects.nonNull(entry.getValue())) {
                    if (entry.getValue().getClass() == Timestamp.class) {
                        String timeStr = LocalDateTime.ofInstant(Instant.ofEpochMilli(((Timestamp) entry.getValue()).getTime()), defaultZoneId).format(dateTimeFormatter);
                        entry.setValue(timeStr);
                    }
                    paramMap.put(entry.getKey().toLowerCase(), entry.getValue()+"");
                }
            }
            paramList.add(paramMap);
        }
    }

    /**
     * 导出列表的excel文件
     * @param fileName 导出文件名
     * @param paramList 需要导出的数据
     * @param titleMap 表头和建的映射
     * @return void
     * @throws
     * @author 皇甫庆远
     * @date 2020/8/28 9:17
     */
    public static void processExportList(String fileName,List<Map<String,String>> paramList,Map<String,String> titleMap, HttpServletResponse response, HttpServletRequest request)throws IOException{
        List<String> titleKey = new ArrayList<>();
        for(String key : titleMap.keySet()){
            titleKey.add(key);
        }
        processExportList(fileName, paramList, titleMap,titleKey ,response, request);
    }

    /**
     * 导出列表的excel文件
     *
     * @param paramList 需导出的数据
     * @param titleMap  表头和键的映射
     * @param titleKey  键
     * @param response
     * @param request
     * @throws IOException
     */
    public static void processExportList(String fileName, List<Map<String, String>> paramList, Map<String, String> titleMap, List<String> titleKey, HttpServletResponse response, HttpServletRequest request) throws IOException {
        //1.在内存中创建一个excel文件
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
        HSSFCellStyle headCellStyle = hssfWorkbook.createCellStyle();
        headCellStyle.setAlignment(HorizontalAlignment.CENTER);
        HSSFFont headCellFont = hssfWorkbook.createFont();
        headCellFont.setFontHeight((short) 240);//20为一个字号,240为12号
        headCellFont.setBold(true);
        headCellStyle.setFont(headCellFont);
        HSSFCellStyle normalCellStyle = hssfWorkbook.createCellStyle();
        normalCellStyle.setAlignment(HorizontalAlignment.CENTER);
        //2.创建工作簿
        HSSFSheet sheet = hssfWorkbook.createSheet();
        for (int i = 0; i < titleKey.size() + 1; i++) {
            sheet.setColumnWidth(i, 5000);
        }
        //3.创建标题行
        HSSFRow titlerRow = sheet.createRow(0);
        HSSFCell headCell0 = titlerRow.createCell(0);
        headCell0.setCellStyle(headCellStyle);
        headCell0.setCellValue("序号");
        for (int i = 0; i < titleKey.size(); i++) {
            HSSFCell headCell = titlerRow.createCell(i + 1);
            headCell.setCellStyle(headCellStyle);
            headCell.setCellValue(titleMap.get(titleKey.get(i)));
        }
        //4.遍历数据,创建数据行
        for (Map<String, String> prjMap : paramList) {
            //获取最后一行的行号
            int lastRowNum = sheet.getLastRowNum();
            HSSFRow dataRow = sheet.createRow(lastRowNum + 1);
            HSSFCell normalCell0 = dataRow.createCell(0);
            normalCell0.setCellStyle(normalCellStyle);
            normalCell0.setCellValue(lastRowNum + 1 + "");
            for (int i = 0; i < titleKey.size(); i++) {
                if (Objects.nonNull(prjMap.get(titleKey.get(i)))) {
                    HSSFCell normalCell = dataRow.createCell(i + 1);
                    normalCell.setCellStyle(normalCellStyle);
                    normalCell.setCellValue(prjMap.get(titleKey.get(i)));
                }
            }
        }
        //6.获取输出流对象
        ServletOutputStream outputStream = response.getOutputStream();

        //7.获取mimeType
        ServletContext servletContext = request.getServletContext();
        String mimeType = servletContext.getMimeType(fileName);
        //8.获取浏览器信息,对文件名进行重新编码
        fileName = filenameEncoding(fileName, request);

        //9.设置信息头
        response.setContentType(mimeType);
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        //10.写出文件,关闭流
        hssfWorkbook.write(outputStream);
        hssfWorkbook.close();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值