diff --git a/src/main/java/com/point/strategy/common/PdfFileHelper.java b/src/main/java/com/point/strategy/common/PdfFileHelper.java index 710a0b2..9dad7dc 100644 --- a/src/main/java/com/point/strategy/common/PdfFileHelper.java +++ b/src/main/java/com/point/strategy/common/PdfFileHelper.java @@ -33,6 +33,100 @@ public class PdfFileHelper { * */ private static int interval = -100; + /** + * 获取字体文件,优先从文件系统读取,然后从classpath读取 + * 兼容JAR包环境和Docker环境 + * @return FontFile对象,包含字体文件路径和临时文件 + */ + private static class FontFile { + public File file; + public boolean isTempFile = false; + + public FontFile(File file, boolean isTempFile) { + this.file = file; + this.isTempFile = isTempFile; + } + } + + /** + * 获取SIMYOU字体文件,兼容JAR包和文件系统 + * @return FontFile对象 + * @throws IOException 字体文件获取失败 + */ + private static FontFile getSimYouFontFile() throws IOException { + // 1. 优先从Docker环境的标准字体目录查找 + String[] dockerFontPaths = { + "/usr/share/fonts/SIMYOU.TTF", + "/usr/local/share/fonts/SIMYOU.TTF", + "/app/fonts/SIMYOU.TTF", + "/app/data/fonts/SIMYOU.TTF" + }; + + for (String fontPath : dockerFontPaths) { + File fontFile = new File(fontPath); + if (fontFile.exists() && fontFile.canRead()) { + log.info("从文件系统找到字体文件: {}", fontPath); + return new FontFile(fontFile, false); + } + } + + // 2. 从classpath中读取字体文件(适用于JAR包环境) + try { + InputStream fontStream = PdfFileHelper.class.getClassLoader().getResourceAsStream("SIMYOU.TTF"); + if (fontStream != null) { + // 创建临时文件 + File tempFontFile = File.createTempFile("SIMYOU", ".TTF"); + tempFontFile.deleteOnExit(); // JVM退出时删除临时文件 + + // 将资源流写入临时文件 + try (InputStream input = fontStream; + FileOutputStream output = new FileOutputStream(tempFontFile)) { + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = input.read(buffer)) != -1) { + output.write(buffer, 0, bytesRead); + } + } + + log.info("从classpath创建临时字体文件: {}", tempFontFile.getAbsolutePath()); + return new FontFile(tempFontFile, true); + } + } catch (Exception e) { + log.warn("从classpath读取字体文件失败: {}", e.getMessage()); + } + + // 3. 尝试使用ResourceUtils(开发环境) + try { + File fontFile = ResourceUtils.getFile("classpath:SIMYOU.TTF"); + if (fontFile.exists() && fontFile.canRead()) { + log.info("使用ResourceUtils读取字体文件: {}", fontFile.getAbsolutePath()); + return new FontFile(fontFile, false); + } + } catch (Exception e) { + log.warn("使用ResourceUtils读取字体文件失败: {}", e.getMessage()); + } + + throw new IOException("无法找到SIMYOU.TTF字体文件,请确保字体文件存在于文件系统或classpath中"); + } + + /** + * 获取BaseFont对象,自动处理字体文件路径 + * @return BaseFont对象 + * @throws Exception 字体创建失败 + */ + private static BaseFont getSimYouBaseFont() throws Exception { + FontFile fontFile = getSimYouFontFile(); + try { + return BaseFont.createFont(fontFile.file.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + } finally { + // 如果是临时文件,清理资源 + if (fontFile.isTempFile && fontFile.file.exists()) { + fontFile.file.delete(); + log.debug("清理临时字体文件: {}", fontFile.file.getAbsolutePath()); + } + } + } + /** * 归档章 单元格宽度 */ @@ -107,8 +201,7 @@ public class PdfFileHelper { text_left = 10; } - File ttfFile = ResourceUtils.getFile("classpath:SIMYOU.TTF"); - BaseFont font = BaseFont.createFont(ttfFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + BaseFont font = getSimYouBaseFont(); //BaseFont font = BaseFont.createFont("C:\\Users\\MI\\Desktop\\13\\SIMYOU.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); @@ -188,8 +281,7 @@ public class PdfFileHelper { int numberOfPages = pdfReader.getNumberOfPages(); - File ttfFile = ResourceUtils.getFile("classpath:SIMYOU.TTF"); - BaseFont font = BaseFont.createFont(ttfFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + BaseFont font = getSimYouBaseFont(); // BaseFont font = BaseFont.createFont("C:\\Users\\MI\\Desktop\\13\\SIMYOU.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); @@ -290,8 +382,7 @@ public class PdfFileHelper { PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(tarFile)); int numberOfPages = pdfReader.getNumberOfPages(); - File ttfFile = ResourceUtils.getFile("classpath:SIMYOU.TTF"); - BaseFont font = BaseFont.createFont(ttfFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + BaseFont font = getSimYouBaseFont(); // BaseFont font = BaseFont.createFont("C:\\Users\\MI\\Desktop\\13\\SIMYOU.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); @@ -599,8 +690,7 @@ public class PdfFileHelper { PdfStamper stamper = new PdfStamper(reader, new FileOutputStream( outputFile)); - File ttfFile = ResourceUtils.getFile("classpath:SIMYOU.TTF"); - BaseFont base = BaseFont.createFont(ttfFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + BaseFont base = getSimYouBaseFont(); // BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED); Rectangle pageRect = null; @@ -663,8 +753,7 @@ public class PdfFileHelper { PdfReader reader = new PdfReader(inputStream); PdfStamper stamper = new PdfStamper(reader, outputStream); - File ttfFile = ResourceUtils.getFile("classpath:SIMYOU.TTF"); - BaseFont base = BaseFont.createFont(ttfFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + BaseFont base = getSimYouBaseFont(); Rectangle pageRect = null; PdfGState gs = new PdfGState(); gs.setFillOpacity(0.2f); diff --git a/src/main/java/com/point/strategy/common/WatermarkMainTest.java b/src/main/java/com/point/strategy/common/WatermarkMainTest.java index 904fdbf..249d6ea 100644 --- a/src/main/java/com/point/strategy/common/WatermarkMainTest.java +++ b/src/main/java/com/point/strategy/common/WatermarkMainTest.java @@ -5,6 +5,7 @@ import com.itextpdf.text.Element; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.*; import org.springframework.util.ResourceUtils; +import lombok.extern.slf4j.Slf4j; import java.awt.*; import java.io.*; @@ -17,8 +18,80 @@ import javax.swing.*; /** * 图片加水印,设置透明度 */ +@Slf4j public class WatermarkMainTest { + /** + * 获取BaseFont对象,自动处理字体文件路径(与PdfFileHelper统一) + * @return BaseFont对象 + * @throws Exception 字体创建失败 + */ + private static BaseFont getSimYouBaseFont() throws Exception { + // 1. 优先从Docker环境标准字体目录查找 + String[] dockerFontPaths = { + "/usr/share/fonts/SIMYOU.TTF", + "/usr/local/share/fonts/SIMYOU.TTF", + "/app/fonts/SIMYOU.TTF", + "/app/data/fonts/SIMYOU.TTF" + }; + + for (String fontPath : dockerFontPaths) { + File fontFile = new File(fontPath); + if (fontFile.exists() && fontFile.canRead()) { + log.info("从文件系统找到字体文件: {}", fontPath); + return BaseFont.createFont(fontFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + } + } + + // 2. 从classpath中读取字体文件(适用于JAR包环境) + try { + InputStream fontStream = WatermarkMainTest.class.getClassLoader().getResourceAsStream("SIMYOU.TTF"); + if (fontStream != null) { + // 创建临时文件 + File tempFontFile = File.createTempFile("SIMYOU", ".TTF"); + tempFontFile.deleteOnExit(); // JVM退出时删除临时文件 + + // 将资源流写入临时文件 + try (InputStream input = fontStream; + FileOutputStream output = new FileOutputStream(tempFontFile)) { + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = input.read(buffer)) != -1) { + output.write(buffer, 0, bytesRead); + } + } + + log.info("从classpath创建临时字体文件: {}", tempFontFile.getAbsolutePath()); + BaseFont font = BaseFont.createFont(tempFontFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + + // 注册删除钩子 + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + if (tempFontFile.exists()) { + tempFontFile.delete(); + log.debug("清理临时字体文件: {}", tempFontFile.getAbsolutePath()); + } + })); + + return font; + } + } catch (Exception e) { + log.warn("从classpath读取字体文件失败: {}", e.getMessage()); + } + + // 3. 尝试使用ResourceUtils(开发环境) + try { + File fontFile = ResourceUtils.getFile("classpath:SIMYOU.TTF"); + if (fontFile.exists() && fontFile.canRead()) { + log.info("使用ResourceUtils读取字体文件: {}", fontFile.getAbsolutePath()); + return BaseFont.createFont(fontFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + } + } catch (Exception e) { + log.warn("使用ResourceUtils读取字体文件失败: {}", e.getMessage()); + } + + throw new IOException("无法找到SIMYOU.TTF字体文件,请确保字体文件存在于文件系统或classpath中"); + } + public static void main(String[] args) throws DocumentException, IOException { List watermarkNames = new ArrayList<>(); watermarkNames.add("xx公司专用"); @@ -59,8 +132,7 @@ public class WatermarkMainTest { // 区分Linux系统与windows系统 String fontsPath = "C:/Windows/Fonts/simsun.ttc";//中文字体路径 // base = com.itextpdf.text.pdf.BaseFont.createFont(fontsPath+",1", com.itextpdf.text.pdf.BaseFont.IDENTITY_H, com.itextpdf.text.pdf.BaseFont.NOT_EMBEDDED); - File ttfFile = ResourceUtils.getFile("classpath:SIMYOU.TTF"); - BaseFont base = BaseFont.createFont(ttfFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + BaseFont base = getSimYouBaseFont(); // 间隔 int interval = -10;