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();
}
}
文件操作工具类
最新推荐文章于 2024-02-19 20:45:44 发布