|
@@ -1,10 +1,17 @@
|
|
|
package com.rongwei.bscommon.sys.service.impl;
|
|
|
|
|
|
import com.aspose.cells.*;
|
|
|
+import com.aspose.pdf.FontRepository;
|
|
|
+import com.aspose.pdf.Page;
|
|
|
+import com.aspose.pdf.TextStamp;
|
|
|
+import com.aspose.pdf.TextState;
|
|
|
import com.aspose.words.Document;
|
|
|
-import com.aspose.words.SaveOutputParameters;
|
|
|
+import com.aspose.words.SaveOptions;
|
|
|
import com.rongwei.bscommon.sys.service.FileFormatConversionService;
|
|
|
import com.rongwei.bscommon.sys.utils.AsposeLicenseConfig;
|
|
|
+import com.rongwei.bscommon.sys.utils.QHSEConstant;
|
|
|
+import com.rongwei.bscommon.sys.utils.QHSEUtils;
|
|
|
+import com.rongwei.rwadmincommon.system.vo.SysUserVo;
|
|
|
import com.rongwei.rwcommon.base.exception.CustomException;
|
|
|
import com.rongwei.rwcommon.utils.StringUtils;
|
|
|
import com.rongwei.rwcommonentity.commonservers.domain.SysFileItemDo;
|
|
@@ -13,13 +20,22 @@ import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import javax.imageio.ImageIO;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.awt.*;
|
|
|
+import java.awt.Color;
|
|
|
+import java.awt.Font;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
import java.io.InputStream;
|
|
|
import java.io.OutputStream;
|
|
|
import java.net.URLEncoder;
|
|
|
import java.nio.file.Files;
|
|
|
import java.nio.file.Paths;
|
|
|
|
|
|
+import static com.rongwei.bscommon.sys.utils.QHSEConstant.ContentType.STREAM;
|
|
|
+import static com.rongwei.bscommon.sys.utils.QHSEConstant.DEFAULT_WATER_MARK;
|
|
|
import static com.rongwei.bscommon.sys.utils.QHSEConstant.FileType.*;
|
|
|
|
|
|
/**
|
|
@@ -43,8 +59,17 @@ public class FileFormatConversionServiceImpl implements FileFormatConversionServ
|
|
|
return sysFileItemDo;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 文件预览并添加PDF
|
|
|
+ * 特殊格式转为PDF
|
|
|
+ * 特殊 格式添加PDF
|
|
|
+ *
|
|
|
+ * @param id
|
|
|
+ * @param response
|
|
|
+ * @param waterMark
|
|
|
+ */
|
|
|
@Override
|
|
|
- public void fileFormatConversion(String id, HttpServletResponse response) {
|
|
|
+ public void fileFormatConversion(String id, HttpServletResponse response, boolean waterMark) {
|
|
|
log.info("开始进行文件格式转换Id为:{}", id);
|
|
|
if (StringUtils.isBlank(id)) {
|
|
|
log.error("参数异常");
|
|
@@ -59,18 +84,31 @@ public class FileFormatConversionServiceImpl implements FileFormatConversionServ
|
|
|
} catch (Exception e) {
|
|
|
throw new RuntimeException(e);
|
|
|
}
|
|
|
- response.setContentType("application/pdf");
|
|
|
+
|
|
|
response.setHeader("Content-Disposition", "inline; filename=" + fileName);
|
|
|
response.setHeader("X-Content-Length", String.valueOf(sysFileItemDo.getFilesize()));
|
|
|
+ String waterMarkStr = "";
|
|
|
+ if (waterMark) {
|
|
|
+ SysUserVo currentUser = QHSEUtils.getCurrentUser();
|
|
|
+ waterMarkStr = String.format(DEFAULT_WATER_MARK, currentUser.getAccount(), currentUser.getName());
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
if (XLSX.equals(lowerCaseFileTYpe) || XLS.equals(lowerCaseFileTYpe)) {
|
|
|
+ response.setContentType(QHSEConstant.ContentType.PDF);
|
|
|
AsposeLicenseConfig.getExcelLicense();
|
|
|
- convertExcelToPdf(null, fullpath, response);
|
|
|
+ convertExcelToPdf(fullpath, response, waterMark, waterMarkStr);
|
|
|
} else if (DOCX.equals(lowerCaseFileTYpe) || DOC.equals(lowerCaseFileTYpe)) {
|
|
|
- convertWordToPdf(null, fullpath, response);
|
|
|
+ response.setContentType(QHSEConstant.ContentType.PDF);
|
|
|
+ convertWordToPdf(fullpath, response, waterMark, waterMarkStr);
|
|
|
+ } else if (PDF.equals(lowerCaseFileTYpe)) {
|
|
|
+ response.setContentType(QHSEConstant.ContentType.PDF);
|
|
|
+ pdfDispose(fullpath, response, waterMark, waterMarkStr);
|
|
|
+ } else if ((PNG.equals(lowerCaseFileTYpe) || JPEG.equals(lowerCaseFileTYpe) || JPG.equals(lowerCaseFileTYpe)) && waterMark) {
|
|
|
+ pictureDispose(fullpath, response, waterMarkStr,lowerCaseFileTYpe);
|
|
|
} else {
|
|
|
try {
|
|
|
- response.setContentType("application/octet-stream");
|
|
|
+ response.setContentType(STREAM);
|
|
|
Files.copy(Paths.get(fullpath), response.getOutputStream());
|
|
|
} catch (Exception e) {
|
|
|
log.error("文件名:{}格式化失败- 原因: {} | 异常类型: {}", sysFileItemDo.getFilename(), e.getMessage(), e.getClass().getSimpleName(), e);
|
|
@@ -80,46 +118,252 @@ public class FileFormatConversionServiceImpl implements FileFormatConversionServ
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- public void convertExcelToPdf(InputStream inputStream, String fullPath, HttpServletResponse response) {
|
|
|
-
|
|
|
+ /**
|
|
|
+ * 图片处理
|
|
|
+ *
|
|
|
+ * @param fullPath
|
|
|
+ * @param response
|
|
|
+ * @param waterMarkStr
|
|
|
+ */
|
|
|
+ public void pictureDispose(String fullPath, HttpServletResponse response, String waterMarkStr, String formatName) {
|
|
|
try (OutputStream out = response.getOutputStream();
|
|
|
InputStream templateStream = Files.newInputStream(Paths.get(fullPath))) {
|
|
|
- LoadOptions loadOptions = new LoadOptions(LoadFormat.XLSX);
|
|
|
- loadOptions.setMemorySetting(MemorySetting.MEMORY_PREFERENCE);
|
|
|
- Workbook workbook = new Workbook(templateStream, loadOptions);
|
|
|
- Worksheet worksheet = workbook.getWorksheets().get(0);
|
|
|
- // 自动调整所有列的宽度
|
|
|
- worksheet.autoFitColumns();
|
|
|
- // 设置 PDF 转换选项
|
|
|
- PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
|
|
|
- pdfSaveOptions.setOnePagePerSheet(true); // 每个工作表单独一页
|
|
|
- pdfSaveOptions.setAllColumnsInOnePagePerSheet(true); // 所有列在一页
|
|
|
- workbook.calculateFormula();
|
|
|
- // 转换为 PDF 并输出到流
|
|
|
- workbook.save(out, pdfSaveOptions);
|
|
|
- out.flush();
|
|
|
+
|
|
|
+ BufferedImage originalImage = ImageIO.read(templateStream);
|
|
|
+
|
|
|
+ // 创建目标图像(保留透明度)
|
|
|
+ int imageType = originalImage.getTransparency() == BufferedImage.TRANSLUCENT
|
|
|
+ ? BufferedImage.TYPE_INT_ARGB
|
|
|
+ : BufferedImage.TYPE_INT_RGB;
|
|
|
+ BufferedImage newImage = new BufferedImage(
|
|
|
+ originalImage.getWidth(),
|
|
|
+ originalImage.getHeight(),
|
|
|
+ imageType
|
|
|
+ );
|
|
|
+
|
|
|
+ // 将原始图像绘制到新图像
|
|
|
+ Graphics2D g2d = newImage.createGraphics();
|
|
|
+ g2d.drawImage(originalImage, 0, 0, null);
|
|
|
+
|
|
|
+ // 设置高质量渲染
|
|
|
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
+ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
|
|
+
|
|
|
+ // 设置水印字体和颜色
|
|
|
+ Font font = new Font("微软雅黑", Font.BOLD, 15);
|
|
|
+ g2d.setFont(font);
|
|
|
+ g2d.setColor(Color.lightGray);
|
|
|
+ // 循环平铺水印
|
|
|
+ for (int x = 0; x < newImage.getWidth() ; x += 200) {
|
|
|
+ for (int y = 0; y < newImage.getHeight() ; y += 100) {
|
|
|
+ // 设置旋转中心点
|
|
|
+ g2d.rotate(Math.toRadians(-45), x, y);
|
|
|
+ g2d.drawString(waterMarkStr, x, y);
|
|
|
+ // 重置旋转(避免累积旋转)
|
|
|
+ g2d.rotate(Math.toRadians(45), x, y);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ g2d.dispose();
|
|
|
+ // 设置响应类型
|
|
|
+ if ("JPEG".equalsIgnoreCase(formatName) || "JPG".equalsIgnoreCase(formatName)) {
|
|
|
+ response.setContentType("image/jpeg");
|
|
|
+ // 处理JPEG透明度
|
|
|
+ BufferedImage jpegImage = new BufferedImage(
|
|
|
+ newImage.getWidth(),
|
|
|
+ newImage.getHeight(),
|
|
|
+ BufferedImage.TYPE_INT_RGB
|
|
|
+ );
|
|
|
+ Graphics2D g = jpegImage.createGraphics();
|
|
|
+ g.drawImage(newImage, 0, 0, Color.WHITE, null);
|
|
|
+ g.dispose();
|
|
|
+ ImageIO.write(jpegImage, formatName, out);
|
|
|
+ } else {
|
|
|
+ response.setContentType("image/png");
|
|
|
+ ImageIO.write(newImage, formatName, out);
|
|
|
+ }
|
|
|
} catch (Exception e) {
|
|
|
- log.error("excel转pdf失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
|
|
|
- throw new RuntimeException("获取预览文件失败!请联系系统管理员");
|
|
|
+ log.error("图片处理失败", e);
|
|
|
+ throw new RuntimeException("文件处理异常");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void convertWordToPdf(InputStream inputStream, String fullPath, HttpServletResponse response) {
|
|
|
+ /**
|
|
|
+ * pdf 处理
|
|
|
+ *
|
|
|
+ * @param fullPath
|
|
|
+ * @param response
|
|
|
+ * @param waterMark
|
|
|
+ * @param waterMarkStr
|
|
|
+ */
|
|
|
+ public void pdfDispose(String fullPath, HttpServletResponse response, boolean waterMark, String waterMarkStr) {
|
|
|
try (OutputStream out = response.getOutputStream();
|
|
|
InputStream templateStream = Files.newInputStream(Paths.get(fullPath))) {
|
|
|
- Document doc = new Document(templateStream);
|
|
|
- // 设置 PDF 转换选项
|
|
|
- PdfSaveOptions options = new PdfSaveOptions();
|
|
|
- options.setCompliance(PdfCompliance.PDF_A_1_A); // 设置PDF/A-1a标准
|
|
|
- // 3. 直接输出到响应流(避免中间文件)
|
|
|
- SaveOutputParameters save = doc.save(out, com.aspose.words.SaveFormat.PDF);
|
|
|
- // 4. 强制刷新缓冲区(确保数据完整传输)
|
|
|
+ com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(templateStream);
|
|
|
+ if (waterMark) {
|
|
|
+ addTextWatermark(pdfDoc, waterMarkStr, 0.5f);
|
|
|
+ }
|
|
|
+ // 转换为 PDF 并输出到流
|
|
|
+ pdfDoc.save(out);
|
|
|
out.flush();
|
|
|
} catch (Exception e) {
|
|
|
- log.error("word转pdf失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
|
|
|
+ log.error("pdf预览失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
|
|
|
throw new RuntimeException("获取预览文件失败!请联系系统管理员");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * excel转PDF
|
|
|
+ *
|
|
|
+ * @param fullPath
|
|
|
+ * @param response
|
|
|
+ * @param waterMark
|
|
|
+ * @param waterMarkStr
|
|
|
+ */
|
|
|
+ public void convertExcelToPdf(String fullPath, HttpServletResponse response, boolean waterMark, String waterMarkStr) {
|
|
|
+ if (waterMark) {
|
|
|
+ try (ByteArrayOutputStream excelPdfStream = new ByteArrayOutputStream();
|
|
|
+ InputStream templateStream = Files.newInputStream(Paths.get(fullPath));
|
|
|
+ OutputStream out = response.getOutputStream();) {
|
|
|
+ // 1. Excel转PDF到内存流
|
|
|
+ LoadOptions loadOptions = new LoadOptions(LoadFormat.XLSX);
|
|
|
+ loadOptions.setMemorySetting(MemorySetting.MEMORY_PREFERENCE);
|
|
|
+ Workbook workbook = new Workbook(templateStream, loadOptions);
|
|
|
+ Worksheet worksheet = workbook.getWorksheets().get(0);
|
|
|
+ worksheet.autoFitColumns();
|
|
|
+ workbook.calculateFormula();
|
|
|
+ PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
|
|
|
+ pdfSaveOptions.setOnePagePerSheet(true);
|
|
|
+ // 关闭 "AllColumnsInOnePagePerSheet" 避免过度压缩
|
|
|
+ pdfSaveOptions.setAllColumnsInOnePagePerSheet(false);
|
|
|
+ // 调整优化策略(可选)
|
|
|
+ pdfSaveOptions.setOptimizationType(PdfOptimizationType.STANDARD); // 平衡质量与大小
|
|
|
+ pdfSaveOptions.setCompliance(PdfCompliance.PDF_A_1_A); // 符合标准格式
|
|
|
+ workbook.save(excelPdfStream, pdfSaveOptions);
|
|
|
+
|
|
|
+ // 2. 使用Aspose.PDF添加水印
|
|
|
+ try (com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(new ByteArrayInputStream(excelPdfStream.toByteArray()))) {
|
|
|
+ addTextWatermark(pdfDoc, waterMarkStr, 0.5f);
|
|
|
+ // 3. 输出最终PDF
|
|
|
+ pdfDoc.save(out);
|
|
|
+ out.flush();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Excel转PDF失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
|
|
|
+ throw new RuntimeException("文件转换失败,请联系系统管理员");
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ try (OutputStream out = response.getOutputStream();
|
|
|
+ InputStream templateStream = Files.newInputStream(Paths.get(fullPath))) {
|
|
|
+ LoadOptions loadOptions = new LoadOptions(LoadFormat.XLSX);
|
|
|
+ loadOptions.setMemorySetting(MemorySetting.MEMORY_PREFERENCE);
|
|
|
+ Workbook workbook = new Workbook(templateStream, loadOptions);
|
|
|
+ Worksheet worksheet = workbook.getWorksheets().get(0);
|
|
|
+ // 自动调整所有列的宽度
|
|
|
+ worksheet.autoFitColumns();
|
|
|
+ // 设置 PDF 转换选项
|
|
|
+ PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
|
|
|
+ pdfSaveOptions.setOnePagePerSheet(true); // 每个工作表单独一页
|
|
|
+ pdfSaveOptions.setAllColumnsInOnePagePerSheet(true); // 所有列在一页
|
|
|
+ pdfSaveOptions.setOptimizationType(PdfOptimizationType.MINIMUM_SIZE);
|
|
|
+ workbook.calculateFormula();
|
|
|
+ // 转换为 PDF 并输出到流
|
|
|
+ workbook.save(out, pdfSaveOptions);
|
|
|
+ out.flush();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("excel转pdf失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
|
|
|
+ throw new RuntimeException("获取预览文件失败!请联系系统管理员");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加文字水印
|
|
|
+ *
|
|
|
+ * @param pdfDoc
|
|
|
+ * @param watermarkText
|
|
|
+ * @param opacity
|
|
|
+ */
|
|
|
+ private void addTextWatermark(com.aspose.pdf.Document pdfDoc, String watermarkText, float opacity) {
|
|
|
+ for (Page page : pdfDoc.getPages()) {
|
|
|
+ // 获取页面实际尺寸(排除边距)
|
|
|
+ double width = page.getMediaBox().getWidth();
|
|
|
+ double height = page.getMediaBox().getHeight();
|
|
|
+
|
|
|
+ // 水印参数配置
|
|
|
+ int fontSize = 36;
|
|
|
+ double rotation = 45; // 启用旋转
|
|
|
+ double spacing = fontSize * 5; // 动态步长(根据字体大小调整)
|
|
|
+
|
|
|
+ // 创建文本样式
|
|
|
+ TextState textState = new TextState();
|
|
|
+ textState.setFontSize(fontSize);
|
|
|
+ textState.setForegroundColor(com.aspose.pdf.Color.getLightGray());
|
|
|
+ textState.setFont(FontRepository.findFont("Arial"));
|
|
|
+
|
|
|
+ // 平铺水印
|
|
|
+ for (double x = -100; x < width; x += spacing) {
|
|
|
+ for (double y = -800; y < height; y += spacing) {
|
|
|
+ TextStamp textStamp = new TextStamp(watermarkText, textState);
|
|
|
+ textStamp.setXIndent(x + 100);
|
|
|
+ textStamp.setYIndent(y + 400);
|
|
|
+ textStamp.setRotateAngle(rotation);
|
|
|
+ textStamp.setOpacity(opacity);
|
|
|
+ textStamp.setZoom(0.4);
|
|
|
+ page.addStamp(textStamp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * word转PDF
|
|
|
+ *
|
|
|
+ * @param fullPath
|
|
|
+ * @param response
|
|
|
+ * @param waterMark
|
|
|
+ * @param waterMarkStr
|
|
|
+ */
|
|
|
+ public void convertWordToPdf(String fullPath, HttpServletResponse response, boolean waterMark, String waterMarkStr) {
|
|
|
+ if (waterMark) {
|
|
|
+ try (ByteArrayOutputStream excelPdfStream = new ByteArrayOutputStream();
|
|
|
+ InputStream templateStream = Files.newInputStream(Paths.get(fullPath));
|
|
|
+ OutputStream out = response.getOutputStream();) {
|
|
|
+
|
|
|
+ Document doc = new Document(templateStream);
|
|
|
+ SaveOptions options = new com.aspose.words.PdfSaveOptions();
|
|
|
+ options.setPrettyFormat(true); // 设置PDF/A-1a标准
|
|
|
+ doc.save(excelPdfStream, options);
|
|
|
+
|
|
|
+ // 2. 使用Aspose.PDF添加水印
|
|
|
+ try (com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(new ByteArrayInputStream(excelPdfStream.toByteArray()))) {
|
|
|
+ addTextWatermark(pdfDoc, waterMarkStr, 0.5f);
|
|
|
+ // 3. 输出最终PDF
|
|
|
+ pdfDoc.save(out);
|
|
|
+ out.flush();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Excel转PDF失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
|
|
|
+ throw new RuntimeException("文件转换失败,请联系系统管理员");
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ try (OutputStream out = response.getOutputStream();
|
|
|
+ InputStream templateStream = Files.newInputStream(Paths.get(fullPath))) {
|
|
|
+ Document doc = new Document(templateStream);
|
|
|
+ // 设置 PDF 转换选项
|
|
|
+ PdfSaveOptions options = new PdfSaveOptions();
|
|
|
+ options.setCompliance(PdfCompliance.PDF_A_1_A); // 设置PDF/A-1a标准
|
|
|
+ // 3. 直接输出到响应流(避免中间文件)
|
|
|
+ doc.save(out, com.aspose.words.SaveFormat.PDF);
|
|
|
+ // 4. 强制刷新缓冲区(确保数据完整传输)
|
|
|
+ out.flush();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("word转pdf失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
|
|
|
+ throw new RuntimeException("获取预览文件失败!请联系系统管理员");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|