package cn.keking.service; import cn.keking.config.ConfigConstants; import cn.keking.model.FileAttribute; import cn.keking.model.FileType; import cn.keking.service.cache.CacheService; import cn.keking.utils.WebUtils; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; /** * @author yudian-it * @date 2017/11/13 */ @Component public class FileHandlerService { private static final String DEFAULT_CONVERTER_CHARSET = System.getProperty("sun.jnu.encoding"); private final String fileDir = ConfigConstants.getFileDir(); private final CacheService cacheService; public FileHandlerService(CacheService cacheService) { this.cacheService = cacheService; } /** * @return 已转换过的文件集合(缓存) */ public Map listConvertedFiles() { return cacheService.getPDFCache(); } /** * @return 已转换过的文件,根据文件名获取 */ public String getConvertedFile(String key) { return cacheService.getPDFCache(key); } /** * @param key pdf本地路径 * @return 已将pdf转换成图片的图片本地相对路径 */ public Integer getConvertedPdfImage(String key) { return cacheService.getPdfImageCache(key); } /** * 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型) * * @param url url * @return 文件类型 */ public FileType typeFromUrl(String url) { String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length()); String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); return this.typeFromFileName(fileName); } private FileType typeFromFileName(String fileName) { String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); return FileType.to(fileType); } /** * 从url中剥离出文件名 * * @param url 格式如:http://www.com.cn/20171113164107_月度绩效表模板(新).xls?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=I D1NOFtAJSPT16E6imv6JWuq0k= * @return 文件名 */ public String getFileNameFromURL(String url) { // 因为url的参数中可能会存在/的情况,所以直接url.lastIndexOf("/")会有问题 // 所以先从?处将url截断,然后运用url.lastIndexOf("/")获取文件名 String noQueryUrl = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length()); return noQueryUrl.substring(noQueryUrl.lastIndexOf("/") + 1); } /** * 从路径中获取文件负 * * @param path 类似这种:C:\Users\yudian-it\Downloads * @return 文件名 */ public String getFileNameFromPath(String path) { return path.substring(path.lastIndexOf(File.separator) + 1); } /** * 获取相对路径 * * @param absolutePath 绝对路径 * @return 相对路径 */ public String getRelativePath(String absolutePath) { return absolutePath.substring(fileDir.length()); } /** * 添加转换后PDF缓存 * * @param fileName pdf文件名 * @param value 缓存相对路径 */ public void addConvertedFile(String fileName, String value) { cacheService.putPDFCache(fileName, value); } /** * 添加转换后图片组缓存 * * @param pdfFilePath pdf文件绝对路径 * @param num 图片张数 */ public void addConvertedPdfImage(String pdfFilePath, int num) { cacheService.putPdfImageCache(pdfFilePath, num); } /** * 获取redis中压缩包内图片文件 * * @param fileKey fileKey * @return 图片文件访问url列表 */ public List getImgCache(String fileKey) { return cacheService.getImgCache(fileKey); } /** * 设置redis中压缩包内图片文件 * * @param fileKey fileKey * @param imgs 图片文件访问url列表 */ public void putImgCache(String fileKey, List imgs) { cacheService.putImgCache(fileKey, imgs); } /** * 对转换后的文件进行操作(改变编码方式) * * @param outFilePath 文件绝对路径 */ public void doActionConvertedFile(String outFilePath) { StringBuilder sb = new StringBuilder(); try (InputStream inputStream = new FileInputStream(outFilePath); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, DEFAULT_CONVERTER_CHARSET))) { String line; while (null != (line = reader.readLine())) { if (line.contains("charset=gb2312")) { line = line.replace("charset=gb2312", "charset=utf-8"); } sb.append(line); } // 添加sheet控制头 sb.append(""); sb.append(""); sb.append(""); } catch (IOException e) { e.printStackTrace(); } // 重新写入文件 try (FileOutputStream fos = new FileOutputStream(outFilePath); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, StandardCharsets.UTF_8))) { writer.write(sb.toString()); } catch (IOException e) { e.printStackTrace(); } } /** * 获取文件后缀 * * @param url url * @return 文件后缀 */ private String suffixFromUrl(String url) { String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length()); String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); return suffixFromFileName(fileName); } private String suffixFromFileName(String fileName) { return fileName.substring(fileName.lastIndexOf(".") + 1); } /** * 获取文件属性 * * @param url url * @return 文件属性 */ public FileAttribute getFileAttribute(String url, HttpServletRequest req) { FileAttribute attribute = new FileAttribute(); String suffix; FileType type; String fileName; String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename"); if (StringUtils.hasText(fullFileName)) { fileName = fullFileName; type = this.typeFromFileName(fullFileName); suffix = suffixFromFileName(fullFileName); } else { fileName = getFileNameFromURL(url); type = typeFromUrl(url); suffix = suffixFromUrl(url); } attribute.setType(type); attribute.setName(fileName); attribute.setSuffix(suffix); attribute.setUrl(url); if (req != null) { String officePreviewType = req.getParameter("officePreviewType"); String fileKey = req.getParameter("fileKey"); if (StringUtils.hasText(officePreviewType)) { attribute.setOfficePreviewType(officePreviewType); } if (StringUtils.hasText(fileKey)) { attribute.setFileKey(fileKey); } } return attribute; } }