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.KkFileUtils; import cn.keking.utils.WebUtils; import cn.keking.web.controller.OnlinePreviewController; import com.aspose.cad.Color; import com.aspose.cad.fileformats.cad.CadDrawTypeMode; import com.aspose.cad.imageoptions.CadRasterizationOptions; import com.aspose.cad.imageoptions.PdfOptions; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.tools.imageio.ImageIOUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.awt.image.BufferedImage; import java.io.*; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @author yudian-it * @date 2017/11/13 */ @Component public class FileHandlerService { private final Logger logger = LoggerFactory.getLogger(FileHandlerService.class); private static final String DEFAULT_CONVERTER_CHARSET = System.getProperty("sun.jnu.encoding"); private final String fileDir = ConfigConstants.getFileDir(); private final CacheService cacheService; @Autowired FileInfoService fileFeignClient; @Value("${server.tomcat.uri-encoding:UTF-8}") private String uriEncoding; 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 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(); } } /** * pdf文件转换成jpg图片集 * @param pdfFilePath pdf文件路径 * @param pdfName pdf文件名称 * @param baseUrl 基础访问地址 * @return 图片访问集合 */ public List pdf2jpg(String pdfFilePath, String pdfName, String baseUrl) { List imageUrls = new ArrayList<>(); Integer imageCount = this.getConvertedPdfImage(pdfFilePath); String imageFileSuffix = ".jpg"; String pdfFolder = pdfName.substring(0, pdfName.length() - 4); String urlPrefix; baseUrl = baseUrl +ConfigConstants.GET_PREVIEW_FILE; try { urlPrefix = baseUrl + URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20"); } catch (UnsupportedEncodingException e) { logger.error("UnsupportedEncodingException", e); urlPrefix = baseUrl + pdfFolder; } String token = "?token="+WebUtils.getTokenFromRequest(); if (imageCount != null && imageCount > 0) { for (int i = 0; i < imageCount; i++) { imageUrls.add(urlPrefix + "/" + i + imageFileSuffix+token); } return imageUrls; } try { File pdfFile = new File(pdfFilePath); PDDocument doc = PDDocument.load(pdfFile); int pageCount = doc.getNumberOfPages(); PDFRenderer pdfRenderer = new PDFRenderer(doc); int index = pdfFilePath.lastIndexOf("."); String folder = pdfFilePath.substring(0, index); File path = new File(folder); if (!path.exists() && !path.mkdirs()) { logger.error("创建转换文件【{}】目录失败,请检查目录权限!", folder); } String imageFilePath; for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) { imageFilePath = folder + File.separator + pageIndex + imageFileSuffix; BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 105, ImageType.RGB); ImageIOUtil.writeImage(image, imageFilePath, 105); imageUrls.add(urlPrefix + "/" + pageIndex + imageFileSuffix+token); } doc.close(); this.addConvertedPdfImage(pdfFilePath, pageCount); } catch (IOException e) { logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e); } return imageUrls; } /** * cad文件转pdf * @param inputFilePath cad文件路径 * @param outputFilePath pdf输出文件路径 * @return 转换是否成功 */ public boolean cadToPdf(String inputFilePath, String outputFilePath) { com.aspose.cad.Image cadImage = com.aspose.cad.Image.load(inputFilePath); CadRasterizationOptions cadRasterizationOptions = new CadRasterizationOptions(); cadRasterizationOptions.setLayouts(new String[]{"Model"}); cadRasterizationOptions.setNoScaling(true); cadRasterizationOptions.setBackgroundColor(Color.getWhite()); cadRasterizationOptions.setPageWidth(cadImage.getWidth()); cadRasterizationOptions.setPageHeight(cadImage.getHeight()); cadRasterizationOptions.setPdfProductLocation("center"); cadRasterizationOptions.setAutomaticLayoutsScaling(true); cadRasterizationOptions.setDrawType(CadDrawTypeMode.UseObjectColor); PdfOptions pdfOptions = new PdfOptions(); pdfOptions.setVectorRasterizationOptions(cadRasterizationOptions); File outputFile = new File(outputFilePath); OutputStream stream; try { stream = new FileOutputStream(outputFile); cadImage.save(stream, pdfOptions); cadImage.close(); return true; } catch (FileNotFoundException e) { logger.error("PDFFileNotFoundException,inputFilePath:{}", inputFilePath, e); return false; } } /** * 获取文件属性 * * @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 = FileType.typeFromFileName(fullFileName); suffix = KkFileUtils.suffixFromFileName(fullFileName); } else { fileName = WebUtils.getFileNameFromURL(url); type = FileType.typeFromUrl(url); suffix = WebUtils.suffixFromUrl(url); } attribute.setType(type); attribute.setName(fileName); attribute.setSuffix(suffix); attribute.setUrl(url); if (req != null) { String officePreviewType = req.getParameter("officePreviewType"); String fileKey = WebUtils.getUrlParameterReg(url,"fileKey"); if (StringUtils.hasText(officePreviewType)) { attribute.setOfficePreviewType(officePreviewType); } if (StringUtils.hasText(fileKey)) { attribute.setFileKey(fileKey); } } return attribute; } public FileAttribute getFileAttributeByFileId(String fileId, HttpServletRequest req) { String token = ""; if (req != null) { token = req.getParameter(OnlinePreviewController.REQ_TOKEN); } FileAttribute attribute = fileFeignClient.getFileAttributeByFileId(fileId); String fullFileName = attribute.getName(); attribute.setType(FileType.typeFromFileName(fullFileName)); // 默认的预览类型(配置属性配置) 也可以通过参数设置 attribute.setOfficePreviewType(ConfigConstants.getOfficePreviewType()); attribute.setFileId(fileId); if (req != null) { String officePreviewType = req.getParameter("officePreviewType"); String fileKey = WebUtils.getUrlParameterReg(fileId,"fileKey"); if (StringUtils.hasText(officePreviewType)) { attribute.setOfficePreviewType(officePreviewType); } if (StringUtils.hasText(fileKey)) { attribute.setFileKey(fileKey); } } return attribute; } /** * @return 已转换过的视频文件集合(缓存) */ public Map listConvertedMedias() { return cacheService.getMediaConvertCache(); } /** * 添加转换后的视频文件缓存 * @param fileName * @param value */ public void addConvertedMedias(String fileName, String value) { cacheService.putMediaConvertCache(fileName, value); } /** * @return 已转换视频文件缓存,根据文件名获取 */ public String getConvertedMedias(String key) { return cacheService.getMediaConvertCache(key); } }