This commit is contained in:
2025-11-22 21:03:27 +08:00
parent 18fe6cbfc5
commit f552f3a1cf
2 changed files with 173 additions and 12 deletions

View File

@@ -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);

View File

@@ -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<String> 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;