diff --git a/server/src/main/java/cn/keking/service/ConfigRefreshComponent.java b/server/src/main/java/cn/keking/config/ConfigRefreshComponent.java similarity index 97% rename from server/src/main/java/cn/keking/service/ConfigRefreshComponent.java rename to server/src/main/java/cn/keking/config/ConfigRefreshComponent.java index 1b6296c0..03eade9f 100644 --- a/server/src/main/java/cn/keking/service/ConfigRefreshComponent.java +++ b/server/src/main/java/cn/keking/config/ConfigRefreshComponent.java @@ -1,7 +1,5 @@ -package cn.keking.service; +package cn.keking.config; -import cn.keking.config.ConfigConstants; -import cn.keking.config.WatermarkConfigConstants; import org.artofsolving.jodconverter.office.OfficeUtils; import org.artofsolving.jodconverter.util.ConfigUtils; import org.slf4j.Logger; @@ -13,6 +11,7 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.Properties; +import java.util.concurrent.TimeUnit; /** * @auther: chenjh @@ -81,7 +80,7 @@ public class ConfigRefreshComponent { setWatermarkConfig(properties); bufferedReader.close(); fileReader.close(); - Thread.sleep(1000L); + TimeUnit.SECONDS.sleep(1); } } catch (IOException | InterruptedException e) { LOGGER.error("读取配置文件异常", e); diff --git a/server/src/main/java/cn/keking/utils/ShedulerClean.java b/server/src/main/java/cn/keking/config/SchedulerCleanConfig.java similarity index 78% rename from server/src/main/java/cn/keking/utils/ShedulerClean.java rename to server/src/main/java/cn/keking/config/SchedulerCleanConfig.java index 3c741664..9817a652 100644 --- a/server/src/main/java/cn/keking/utils/ShedulerClean.java +++ b/server/src/main/java/cn/keking/config/SchedulerCleanConfig.java @@ -1,7 +1,7 @@ -package cn.keking.utils; +package cn.keking.config; -import cn.keking.config.ConfigConstants; import cn.keking.service.cache.CacheService; +import cn.keking.utils.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; @@ -14,13 +14,13 @@ import org.springframework.stereotype.Component; */ @Component @ConditionalOnExpression("'${cache.clean.enabled:false}'.equals('true')") -public class ShedulerClean { +public class SchedulerCleanConfig { - private final Logger logger = LoggerFactory.getLogger(ShedulerClean.class); + private final Logger logger = LoggerFactory.getLogger(SchedulerCleanConfig.class); private final CacheService cacheService; - public ShedulerClean(CacheService cacheService) { + public SchedulerCleanConfig(CacheService cacheService) { this.cacheService = cacheService; } diff --git a/server/src/main/java/cn/keking/model/FileType.java b/server/src/main/java/cn/keking/model/FileType.java index daea9f42..08a71872 100644 --- a/server/src/main/java/cn/keking/model/FileType.java +++ b/server/src/main/java/cn/keking/model/FileType.java @@ -50,9 +50,25 @@ public enum FileType { FILE_TYPE_MAPPER.put("dwg", FileType.cad); } - public static FileType to(String fileType){ + private static FileType to(String fileType){ return FILE_TYPE_MAPPER.getOrDefault(fileType,other); } + /** + * 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型) + * + * @param url url + * @return 文件类型 + */ + public static FileType typeFromUrl(String url) { + String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length()); + String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); + return typeFromFileName(fileName); + } + + public static FileType typeFromFileName(String fileName) { + String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); + return FileType.to(fileType); + } private final String instanceName; diff --git a/server/src/main/java/cn/keking/model/ReturnResponse.java b/server/src/main/java/cn/keking/model/ReturnResponse.java index 6595341d..7f91c5d4 100644 --- a/server/src/main/java/cn/keking/model/ReturnResponse.java +++ b/server/src/main/java/cn/keking/model/ReturnResponse.java @@ -4,11 +4,18 @@ import java.io.Serializable; /** * 接口返回值结构 + * * @author yudian-it * @date 2017/11/17 */ -public class ReturnResponse implements Serializable{ +public class ReturnResponse implements Serializable { private static final long serialVersionUID = 313975329998789878L; + + public static final int SUCCESS_CODE = 0; + public static final int FAILURE_CODE = 1; + public static final String SUCCESS_MSG = "SUCCESS"; + public static final String FAILURE_MSG = "FAILURE"; + /** * 返回状态 * 0. 成功 @@ -31,6 +38,30 @@ public class ReturnResponse implements Serializable{ this.content = content; } + public static ReturnResponse failure(String errMsg) { + return new ReturnResponse<>(FAILURE_CODE, errMsg, null); + } + + public static ReturnResponse failure() { + return failure(FAILURE_MSG); + } + + public static ReturnResponse success(){ + return success(null); + } + + public static ReturnResponse success(Object content) { + return new ReturnResponse<>(SUCCESS_CODE, SUCCESS_MSG, content); + } + + public boolean isSuccess(){ + return SUCCESS_CODE == code; + } + + public boolean isFailure(){ + return !isSuccess(); + } + public int getCode() { return code; } diff --git a/server/src/main/java/cn/keking/service/CompressFileReader.java b/server/src/main/java/cn/keking/service/CompressFileReader.java index 79ad841f..c396e56b 100644 --- a/server/src/main/java/cn/keking/service/CompressFileReader.java +++ b/server/src/main/java/cn/keking/service/CompressFileReader.java @@ -67,7 +67,7 @@ public class CompressFileReader { } String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName); parentName = (level - 1) + "_" + parentName; - FileType type = fileHandlerService.typeFromUrl(childName); + FileType type = FileType.typeFromUrl(childName); if (type.equals(FileType.picture)) {//添加图片文件到图片列表 imgUrls.add(baseUrl + childName); } @@ -120,7 +120,7 @@ public class CompressFileReader { headersToBeExtracted.add(Collections.singletonMap(childName, header)); } String parentName = getLast2FileName(fullName, "\\", archiveFileName); - FileType type = fileHandlerService.typeFromUrl(childName); + FileType type = FileType.typeFromUrl(childName); if (type.equals(FileType.picture)) {//添加图片文件到图片列表 imgUrls.add(baseUrl + childName); } @@ -163,7 +163,7 @@ public class CompressFileReader { } String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName); parentName = (level - 1) + "_" + parentName; - FileType type = fileHandlerService.typeFromUrl(childName); + FileType type = FileType.typeFromUrl(childName); if (type.equals(FileType.picture)) {//添加图片文件到图片列表 imgUrls.add(baseUrl + childName); } diff --git a/server/src/main/java/cn/keking/service/FileConvertQueueTask.java b/server/src/main/java/cn/keking/service/FileConvertQueueTask.java index d6390887..5140e8a4 100644 --- a/server/src/main/java/cn/keking/service/FileConvertQueueTask.java +++ b/server/src/main/java/cn/keking/service/FileConvertQueueTask.java @@ -10,6 +10,7 @@ import org.springframework.ui.ExtendedModelMap; import javax.annotation.PostConstruct; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; /** * Created by kl on 2018/1/19. @@ -70,7 +71,7 @@ public class FileConvertQueueTask { } } catch (Exception e) { try { - Thread.sleep(1000*10); + TimeUnit.SECONDS.sleep(10); } catch (Exception ex){ ex.printStackTrace(); } diff --git a/server/src/main/java/cn/keking/service/FileHandlerService.java b/server/src/main/java/cn/keking/service/FileHandlerService.java index d6918d6f..3c82d913 100644 --- a/server/src/main/java/cn/keking/service/FileHandlerService.java +++ b/server/src/main/java/cn/keking/service/FileHandlerService.java @@ -4,13 +4,28 @@ 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.FileUtils; import cn.keking.utils.WebUtils; +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.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; @@ -21,10 +36,15 @@ import java.util.Map; @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; + @Value("${server.tomcat.uri-encoding:UTF-8}") + private String uriEncoding; + public FileHandlerService(CacheService cacheService) { this.cacheService = cacheService; } @@ -51,35 +71,6 @@ public class FileHandlerService { 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); - } /** * 从路径中获取文件负 @@ -174,19 +165,87 @@ public class FileHandlerService { } /** - * 获取文件后缀 - * - * @param url url - * @return 文件后缀 + * pdf文件转换成jpg图片集 + * @param pdfFilePath pdf文件路径 + * @param pdfName pdf文件名称 + * @param baseUrl 基础访问地址 + * @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); + 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; + try { + urlPrefix = baseUrl + URLEncoder.encode(URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20"), uriEncoding); + } catch (UnsupportedEncodingException e) { + logger.error("UnsupportedEncodingException", e); + urlPrefix = baseUrl + pdfFolder; + } + if (imageCount != null && imageCount > 0) { + for (int i = 0; i < imageCount; i++) + imageUrls.add(urlPrefix + "/" + i + imageFileSuffix); + 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); + } + doc.close(); + this.addConvertedPdfImage(pdfFilePath, pageCount); + } catch (IOException e) { + logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e); + } + return imageUrls; } - private String suffixFromFileName(String fileName) { - return fileName.substring(fileName.lastIndexOf(".") + 1); + /** + * 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; + } } /** @@ -203,12 +262,12 @@ public class FileHandlerService { String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename"); if (StringUtils.hasText(fullFileName)) { fileName = fullFileName; - type = this.typeFromFileName(fullFileName); - suffix = suffixFromFileName(fullFileName); + type = FileType.typeFromFileName(fullFileName); + suffix = FileUtils.suffixFromFileName(fullFileName); } else { - fileName = getFileNameFromURL(url); - type = typeFromUrl(url); - suffix = suffixFromUrl(url); + fileName = WebUtils.getFileNameFromURL(url); + type = FileType.typeFromUrl(url); + suffix = WebUtils.suffixFromUrl(url); } attribute.setType(type); attribute.setName(fileName); diff --git a/server/src/main/java/cn/keking/extend/ControlDocumentFormatRegistry.java b/server/src/main/java/cn/keking/service/OfficePluginExtendFormatRegistry.java similarity index 98% rename from server/src/main/java/cn/keking/extend/ControlDocumentFormatRegistry.java rename to server/src/main/java/cn/keking/service/OfficePluginExtendFormatRegistry.java index 1ea624cf..918e7e58 100644 --- a/server/src/main/java/cn/keking/extend/ControlDocumentFormatRegistry.java +++ b/server/src/main/java/cn/keking/service/OfficePluginExtendFormatRegistry.java @@ -1,4 +1,4 @@ -package cn.keking.extend; +package cn.keking.service; import org.artofsolving.jodconverter.document.DocumentFamily; import org.artofsolving.jodconverter.document.DocumentFormat; @@ -13,9 +13,9 @@ import java.util.Map; * @author yudian-it * @date 2017/12/5 */ -public class ControlDocumentFormatRegistry extends SimpleDocumentFormatRegistry { +public class OfficePluginExtendFormatRegistry extends SimpleDocumentFormatRegistry { - public ControlDocumentFormatRegistry() { + public OfficePluginExtendFormatRegistry() { DocumentFormat pdf = new DocumentFormat("Portable Document Format", "pdf", "application/pdf"); pdf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer_pdf_Export")); pdf.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc_pdf_Export")); diff --git a/server/src/main/java/cn/keking/service/OfficePluginManager.java b/server/src/main/java/cn/keking/service/OfficePluginManager.java index 7e3776f9..056f191b 100644 --- a/server/src/main/java/cn/keking/service/OfficePluginManager.java +++ b/server/src/main/java/cn/keking/service/OfficePluginManager.java @@ -1,7 +1,6 @@ package cn.keking.service; import com.sun.star.document.UpdateDocMode; -import cn.keking.extend.ControlDocumentFormatRegistry; import org.apache.commons.lang3.StringUtils; import org.artofsolving.jodconverter.OfficeDocumentConverter; import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration; @@ -72,7 +71,7 @@ public class OfficePluginManager { } public OfficeDocumentConverter getDocumentConverter() { - OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, new ControlDocumentFormatRegistry()); + OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, new OfficePluginExtendFormatRegistry()); converter.setDefaultLoadProperties(getLoadProperties()); return converter; } diff --git a/server/src/main/java/cn/keking/service/OfficeToPdfService.java b/server/src/main/java/cn/keking/service/OfficeToPdfService.java index 52b81814..98cfaf4e 100644 --- a/server/src/main/java/cn/keking/service/OfficeToPdfService.java +++ b/server/src/main/java/cn/keking/service/OfficeToPdfService.java @@ -1,6 +1,8 @@ package cn.keking.service; import org.artofsolving.jodconverter.OfficeDocumentConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.io.File; @@ -10,6 +12,8 @@ import java.io.File; */ @Component public class OfficeToPdfService { + + private final static Logger logger = LoggerFactory.getLogger(OfficeToPdfService.class); private final OfficePluginManager officePluginManager; public OfficeToPdfService(OfficePluginManager officePluginManager) { @@ -21,12 +25,11 @@ public class OfficeToPdfService { } - public static void converterFile(File inputFile, String outputFilePath_end, - OfficeDocumentConverter converter) { + public static void converterFile(File inputFile, String outputFilePath_end, OfficeDocumentConverter converter) { File outputFile = new File(outputFilePath_end); // 假如目标路径不存在,则新建该路径 - if (!outputFile.getParentFile().exists()) { - outputFile.getParentFile().mkdirs(); + if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) { + logger.error("创建目录【{}】失败,请检查目录权限!",outputFilePath_end); } converter.convert(inputFile, outputFile); } diff --git a/server/src/main/java/cn/keking/service/cache/impl/CacheServiceRedisImpl.java b/server/src/main/java/cn/keking/service/cache/impl/CacheServiceRedisImpl.java index 71b18483..fb9cc483 100644 --- a/server/src/main/java/cn/keking/service/cache/impl/CacheServiceRedisImpl.java +++ b/server/src/main/java/cn/keking/service/cache/impl/CacheServiceRedisImpl.java @@ -28,19 +28,11 @@ public class CacheServiceRedisImpl implements CacheService { } @Override - public void initPDFCachePool(Integer capacity) { - - } - + public void initPDFCachePool(Integer capacity) { } @Override - public void initIMGCachePool(Integer capacity) { - - } - + public void initIMGCachePool(Integer capacity) { } @Override - public void initPdfImagesCachePool(Integer capacity) { - - } + public void initPdfImagesCachePool(Integer capacity) { } @Override public void putPDFCache(String key, String value) { diff --git a/server/src/main/java/cn/keking/service/cache/impl/CacheServiceRocksDBImpl.java b/server/src/main/java/cn/keking/service/cache/impl/CacheServiceRocksDBImpl.java index 44056810..bc41f27a 100644 --- a/server/src/main/java/cn/keking/service/cache/impl/CacheServiceRocksDBImpl.java +++ b/server/src/main/java/cn/keking/service/cache/impl/CacheServiceRocksDBImpl.java @@ -31,11 +31,8 @@ public class CacheServiceRocksDBImpl implements CacheService { } private static final String DB_PATH = ConfigUtils.getHomePath() + File.separator + "cache"; - private static final int QUEUE_SIZE = 500000; - private static final Logger LOGGER = LoggerFactory.getLogger(CacheServiceRocksDBImpl.class); - private final BlockingQueue blockingQueue = new ArrayBlockingQueue<>(QUEUE_SIZE); private RocksDB db; diff --git a/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java index e16c3a64..f66a33a9 100644 --- a/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java @@ -4,10 +4,8 @@ import cn.keking.config.ConfigConstants; import cn.keking.model.FileAttribute; import cn.keking.model.ReturnResponse; import cn.keking.service.FilePreview; -import cn.keking.utils.CadUtils; import cn.keking.utils.DownloadUtils; import cn.keking.service.FileHandlerService; -import cn.keking.utils.PdfUtils; import cn.keking.web.filter.BaseUrlFilter; import org.springframework.stereotype.Service; import org.springframework.ui.Model; @@ -22,43 +20,37 @@ import static cn.keking.service.impl.OfficeFilePreviewImpl.getPreviewType; @Service public class CadFilePreviewImpl implements FilePreview { - private final FileHandlerService fileHandlerService; - private final CadUtils cadUtils; - private final PdfUtils pdfUtils; - - public CadFilePreviewImpl(FileHandlerService fileHandlerService, CadUtils cadUtils, PdfUtils pdfUtils) { - this.fileHandlerService = fileHandlerService; - this.cadUtils = cadUtils; - this.pdfUtils = pdfUtils; - - } - private static final String OFFICE_PREVIEW_TYPE_IMAGE = "image"; private static final String OFFICE_PREVIEW_TYPE_ALL_IMAGES = "allImages"; private static final String FILE_DIR = ConfigConstants.getFileDir(); + private final FileHandlerService fileHandlerService; + + public CadFilePreviewImpl(FileHandlerService fileHandlerService) { + this.fileHandlerService = fileHandlerService; + } @Override public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { // 预览Type,参数传了就取参数的,没传取系统默认 String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString(); String baseUrl = BaseUrlFilter.getBaseUrl(); - String suffix=fileAttribute.getSuffix(); - String fileName=fileAttribute.getName(); + String suffix = fileAttribute.getSuffix(); + String fileName = fileAttribute.getName(); String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf"; String outFilePath = FILE_DIR + pdfName; // 判断之前是否已转换过,如果转换过,直接返回,否则执行转换 if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { String filePath; ReturnResponse response = DownloadUtils.downLoad(fileAttribute, null); - if (0 != response.getCode()) { + if (response.isFailure()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); return "fileNotSupported"; } filePath = response.getContent(); if (StringUtils.hasText(outFilePath)) { - boolean convertResult = cadUtils.cadToPdf(filePath, outFilePath); + boolean convertResult = fileHandlerService.cadToPdf(filePath, outFilePath); if (!convertResult) { model.addAttribute("fileType", suffix); model.addAttribute("msg", "cad文件转换异常,请联系管理员"); @@ -71,7 +63,7 @@ public class CadFilePreviewImpl implements FilePreview { } } if (baseUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType))) { - return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, pdfUtils, OFFICE_PREVIEW_TYPE_IMAGE); + return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE); } model.addAttribute("pdfUrl", pdfName); return "pdf"; diff --git a/server/src/main/java/cn/keking/service/impl/CompressFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/CompressFilePreviewImpl.java index e351844f..bfc4a90b 100644 --- a/server/src/main/java/cn/keking/service/impl/CompressFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/CompressFilePreviewImpl.java @@ -34,7 +34,7 @@ public class CompressFilePreviewImpl implements FilePreview { // 判断文件名是否存在(redis缓存读取) if (!StringUtils.hasText(fileHandlerService.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) { ReturnResponse response = DownloadUtils.downLoad(fileAttribute, fileName); - if (0 != response.getCode()) { + if (response.isFailure()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); return "fileNotSupported"; diff --git a/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java index d978042a..0ea750b6 100644 --- a/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java @@ -8,6 +8,7 @@ import cn.keking.service.FileHandlerService; import cn.keking.web.filter.BaseUrlFilter; import org.springframework.stereotype.Service; import org.springframework.ui.Model; + /** * @author : kl * @authorboke : kailing.pub @@ -28,7 +29,7 @@ public class MediaFilePreviewImpl implements FilePreview { // 不是http开头,浏览器不能直接访问,需下载到本地 if (url != null && !url.toLowerCase().startsWith("http")) { ReturnResponse response = DownloadUtils.downLoad(fileAttribute, fileAttribute.getName()); - if (0 != response.getCode()) { + if (!response.isSuccess()) { model.addAttribute("fileType", fileAttribute.getSuffix()); model.addAttribute("msg", response.getMsg()); return "fileNotSupported"; @@ -39,7 +40,7 @@ public class MediaFilePreviewImpl implements FilePreview { model.addAttribute("mediaUrl", url); } model.addAttribute("mediaUrl", url); - String suffix=fileAttribute.getSuffix(); + String suffix = fileAttribute.getSuffix(); if ("flv".equalsIgnoreCase(suffix)) { return "flv"; } diff --git a/server/src/main/java/cn/keking/service/impl/OfficeFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/OfficeFilePreviewImpl.java index dcbbd694..dbd60c0a 100644 --- a/server/src/main/java/cn/keking/service/impl/OfficeFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/OfficeFilePreviewImpl.java @@ -7,7 +7,6 @@ import cn.keking.service.FilePreview; import cn.keking.utils.DownloadUtils; import cn.keking.service.FileHandlerService; import cn.keking.service.OfficeToPdfService; -import cn.keking.utils.PdfUtils; import cn.keking.web.filter.BaseUrlFilter; import org.springframework.stereotype.Service; import org.springframework.ui.Model; @@ -22,20 +21,18 @@ import java.util.List; @Service public class OfficeFilePreviewImpl implements FilePreview { + public static final String OFFICE_PREVIEW_TYPE_IMAGE = "image"; + public static final String OFFICE_PREVIEW_TYPE_ALL_IMAGES = "allImages"; + private static final String FILE_DIR = ConfigConstants.getFileDir(); + private final FileHandlerService fileHandlerService; - private final PdfUtils pdfUtils; private final OfficeToPdfService officeToPdfService; - public OfficeFilePreviewImpl(FileHandlerService fileHandlerService, PdfUtils pdfUtils, OfficeToPdfService officeToPdfService) { + public OfficeFilePreviewImpl(FileHandlerService fileHandlerService, OfficeToPdfService officeToPdfService) { this.fileHandlerService = fileHandlerService; - this.pdfUtils = pdfUtils; this.officeToPdfService = officeToPdfService; } - public static final String OFFICE_PREVIEW_TYPE_IMAGE = "image"; - public static final String OFFICE_PREVIEW_TYPE_ALL_IMAGES = "allImages"; - private static final String FILE_DIR = ConfigConstants.getFileDir(); - @Override public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { // 预览Type,参数传了就取参数的,没传取系统默认 @@ -50,7 +47,7 @@ public class OfficeFilePreviewImpl implements FilePreview { if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { String filePath; ReturnResponse response = DownloadUtils.downLoad(fileAttribute, null); - if (0 != response.getCode()) { + if (response.isFailure()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); return "fileNotSupported"; @@ -69,14 +66,14 @@ public class OfficeFilePreviewImpl implements FilePreview { } } if (!isHtml && baseUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType))) { - return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, pdfUtils, OFFICE_PREVIEW_TYPE_IMAGE); + return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE); } model.addAttribute("pdfUrl", pdfName); return isHtml ? "html" : "pdf"; } - static String getPreviewType(Model model, FileAttribute fileAttribute, String officePreviewType, String baseUrl, String pdfName, String outFilePath, PdfUtils pdfUtils, String officePreviewTypeImage) { - List imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, baseUrl); + static String getPreviewType(Model model, FileAttribute fileAttribute, String officePreviewType, String baseUrl, String pdfName, String outFilePath, FileHandlerService fileHandlerService, String officePreviewTypeImage) { + List imageUrls = fileHandlerService.pdf2jpg(outFilePath, pdfName, baseUrl); if (imageUrls == null || imageUrls.size() < 1) { model.addAttribute("msg", "office转图片异常,请联系管理员"); model.addAttribute("fileType",fileAttribute.getSuffix()); diff --git a/server/src/main/java/cn/keking/service/impl/PdfFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/PdfFilePreviewImpl.java index b0f1bf93..4f29052f 100644 --- a/server/src/main/java/cn/keking/service/impl/PdfFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/PdfFilePreviewImpl.java @@ -6,7 +6,6 @@ import cn.keking.model.ReturnResponse; import cn.keking.service.FilePreview; import cn.keking.utils.DownloadUtils; import cn.keking.service.FileHandlerService; -import cn.keking.utils.PdfUtils; import cn.keking.web.filter.BaseUrlFilter; import org.springframework.stereotype.Service; import org.springframework.ui.Model; @@ -21,12 +20,10 @@ import java.util.List; public class PdfFilePreviewImpl implements FilePreview { private final FileHandlerService fileHandlerService; - private final PdfUtils pdfUtils; private static final String FILE_DIR = ConfigConstants.getFileDir(); - public PdfFilePreviewImpl(FileHandlerService fileHandlerService, PdfUtils pdfUtils) { + public PdfFilePreviewImpl(FileHandlerService fileHandlerService) { this.fileHandlerService = fileHandlerService; - this.pdfUtils = pdfUtils; } @Override @@ -41,7 +38,7 @@ public class PdfFilePreviewImpl implements FilePreview { //当文件不存在时,就去下载 if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { ReturnResponse response = DownloadUtils.downLoad(fileAttribute, fileName); - if (0 != response.getCode()) { + if (response.isFailure()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); return "fileNotSupported"; @@ -52,7 +49,7 @@ public class PdfFilePreviewImpl implements FilePreview { fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath)); } } - List imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, baseUrl); + List imageUrls = fileHandlerService.pdf2jpg(outFilePath, pdfName, baseUrl); if (imageUrls == null || imageUrls.size() < 1) { model.addAttribute("msg", "pdf转图片异常,请联系管理员"); model.addAttribute("fileType",fileAttribute.getSuffix()); @@ -70,7 +67,7 @@ public class PdfFilePreviewImpl implements FilePreview { if (url != null && !url.toLowerCase().startsWith("http")) { if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { ReturnResponse response = DownloadUtils.downLoad(fileAttribute, pdfName); - if (0 != response.getCode()) { + if (response.isFailure()) { model.addAttribute("fileType", suffix); model.addAttribute("msg", response.getMsg()); return "fileNotSupported"; diff --git a/server/src/main/java/cn/keking/service/impl/PictureFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/PictureFilePreviewImpl.java index 11631676..6122eae2 100644 --- a/server/src/main/java/cn/keking/service/impl/PictureFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/PictureFilePreviewImpl.java @@ -36,7 +36,7 @@ public class PictureFilePreviewImpl implements FilePreview { // 不是http开头,浏览器不能直接访问,需下载到本地 if (url != null && !url.toLowerCase().startsWith("http")) { ReturnResponse response = DownloadUtils.downLoad(fileAttribute, null); - if (0 != response.getCode()) { + if (response.isFailure()) { model.addAttribute("fileType", fileAttribute.getSuffix()); model.addAttribute("msg", response.getMsg()); return "fileNotSupported"; diff --git a/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java index 10d7b65d..401180f0 100644 --- a/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java +++ b/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java @@ -27,7 +27,7 @@ public class SimTextFilePreviewImpl implements FilePreview { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { String fileName = fileAttribute.getName(); ReturnResponse response = DownloadUtils.downLoad(fileAttribute, fileName); - if (0 != response.getCode()) { + if (response.isFailure()) { model.addAttribute("msg", response.getMsg()); model.addAttribute("fileType", fileAttribute.getSuffix()); return "fileNotSupported"; diff --git a/server/src/main/java/cn/keking/utils/CadUtils.java b/server/src/main/java/cn/keking/utils/CadUtils.java deleted file mode 100644 index a17188d2..00000000 --- a/server/src/main/java/cn/keking/utils/CadUtils.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.keking.utils; - -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.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.OutputStream; - -/** - * @author chenjhc - * @since 2019/11/21 14:34 - */ -@Component -public class CadUtils { - - private final Logger logger = LoggerFactory.getLogger(CadUtils.class); - - 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; - } - } -} diff --git a/server/src/main/java/cn/keking/utils/FileUtils.java b/server/src/main/java/cn/keking/utils/FileUtils.java index 8c6d1894..bf0d64e5 100644 --- a/server/src/main/java/cn/keking/utils/FileUtils.java +++ b/server/src/main/java/cn/keking/utils/FileUtils.java @@ -57,6 +57,16 @@ public class FileUtils { } } + /** + * 通过文件名获取文件后缀 + * @param fileName 文件名称 + * @return 文件后缀 + */ + public static String suffixFromFileName(String fileName) { + return fileName.substring(fileName.lastIndexOf(".") + 1); + } + + /** * 根据文件路径删除文件 * diff --git a/server/src/main/java/cn/keking/utils/PdfUtils.java b/server/src/main/java/cn/keking/utils/PdfUtils.java deleted file mode 100644 index 63d9141a..00000000 --- a/server/src/main/java/cn/keking/utils/PdfUtils.java +++ /dev/null @@ -1,79 +0,0 @@ -package cn.keking.utils; - -import cn.keking.service.FileHandlerService; -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.Value; -import org.springframework.stereotype.Component; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.List; - -@Component -public class PdfUtils { - - private final Logger logger = LoggerFactory.getLogger(PdfUtils.class); - - private final FileHandlerService fileHandlerService; - - @Value("${server.tomcat.uri-encoding:UTF-8}") - private String uriEncoding; - - public PdfUtils(FileHandlerService fileHandlerService) { - this.fileHandlerService = fileHandlerService; - } - - public List pdf2jpg(String pdfFilePath, String pdfName, String baseUrl) { - List imageUrls = new ArrayList<>(); - Integer imageCount = fileHandlerService.getConvertedPdfImage(pdfFilePath); - String imageFileSuffix = ".jpg"; - String pdfFolder = pdfName.substring(0, pdfName.length() - 4); - String urlPrefix = null; - try { - urlPrefix = baseUrl + URLEncoder.encode(URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20"), uriEncoding); - } catch (UnsupportedEncodingException e) { - logger.error("UnsupportedEncodingException", e); - urlPrefix = baseUrl + pdfFolder; - } - if (imageCount != null && imageCount > 0) { - for (int i = 0; i < imageCount ; i++) - imageUrls.add(urlPrefix + "/" + i + imageFileSuffix); - 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(); - } - 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); - } - doc.close(); - fileHandlerService.addConvertedPdfImage(pdfFilePath, pageCount); - } catch (IOException e) { - logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e); - } - return imageUrls; - } -} diff --git a/server/src/main/java/cn/keking/utils/WebUtils.java b/server/src/main/java/cn/keking/utils/WebUtils.java index 1f7e6946..7bebf61b 100644 --- a/server/src/main/java/cn/keking/utils/WebUtils.java +++ b/server/src/main/java/cn/keking/utils/WebUtils.java @@ -57,4 +57,30 @@ public class WebUtils { } return strAllParam; } + + /** + * 从url中剥离出文件名 + * + * @param url 格式如:http://www.com.cn/20171113164107_月度绩效表模板(新).xls?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=I D1NOFtAJSPT16E6imv6JWuq0k= + * @return 文件名 + */ + public static 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); + } + + + /** + * 从url中获取文件后缀 + * + * @param url url + * @return 文件后缀 + */ + public static String suffixFromUrl(String url) { + String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length()); + String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); + return FileUtils.suffixFromFileName(fileName); + } } diff --git a/server/src/main/java/cn/keking/web/controller/FileController.java b/server/src/main/java/cn/keking/web/controller/FileController.java index e6279135..165df5f5 100644 --- a/server/src/main/java/cn/keking/web/controller/FileController.java +++ b/server/src/main/java/cn/keking/web/controller/FileController.java @@ -28,9 +28,7 @@ public class FileController { private final Logger logger = LoggerFactory.getLogger(FileController.class); private final String fileDir = ConfigConstants.getFileDir(); - private final String demoDir = "demo"; - private final String demoPath = demoDir + File.separator; @RequestMapping(value = "fileUpload", method = RequestMethod.POST) @@ -49,7 +47,7 @@ public class FileController { } // 判断是否存在同名文件 if (existsFile(fileName)) { - return new ObjectMapper().writeValueAsString(new ReturnResponse(1, "存在同名文件,请先删除原有文件再次上传", null)); + return new ObjectMapper().writeValueAsString(ReturnResponse.failure("存在同名文件,请先删除原有文件再次上传")); } File outFile = new File(fileDir + demoPath); if (!outFile.exists() && !outFile.mkdirs()) { @@ -58,10 +56,10 @@ public class FileController { logger.info("上传文件:{}", fileDir + demoPath + fileName); try(InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(fileDir + demoPath + fileName)) { StreamUtils.copy(in, out); - return new ObjectMapper().writeValueAsString(new ReturnResponse(0, "SUCCESS", null)); + return new ObjectMapper().writeValueAsString(ReturnResponse.success(null)); } catch (IOException e) { logger.error("文件上传失败", e); - return new ObjectMapper().writeValueAsString(new ReturnResponse(1, "FAILURE", null)); + return new ObjectMapper().writeValueAsString(ReturnResponse.failure()); } } @@ -75,7 +73,7 @@ public class FileController { if (file.exists() && !file.delete()) { logger.error("删除文件【{}】失败,请检查目录权限!",file.getPath()); } - return new ObjectMapper().writeValueAsString(new ReturnResponse(0, "SUCCESS", null)); + return new ObjectMapper().writeValueAsString(ReturnResponse.success()); } @RequestMapping(value = "listFiles", method = RequestMethod.GET)