简述
最近有个需求需要给pdf加文字水印,于是开始搜索大法,但是发现网络上的代码基本都是将字体文件直接放在jar包里面。个人强迫症发作(手动狗头),想要像poi一样直接加载系统字体,于是研究了一下午pdfbox的源代码,发现FontFileFinder类可以实现这个功能。废话不多说,直接上代码。
引入依赖
<!-- pdfbox-->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- 提供 HttpServlet 相关类 -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
新增水印配置类
@Data
@NoArgsConstructor
public class PdfWatermarkProperties {
public PdfWatermarkProperties(String content) {
this.content = content;
}
/**
* 文字水印内容
*/
private String content = "";
/**
* ttf类型字体文件. 为null则使用默认字体
*/
private File fontFile;
private float fontSize = 13;
/**
* cmyk颜色.参数值范围为 0-255
*/
private int[] color = {0, 0, 0, 210};
/**
* 透明度
*/
private float transparency = 0.3f;
/**
* 倾斜度. 默认30°
*/
private double rotate = 0.3;
/**
* 初始添加水印的点位
*/
private int x = -10;
private int y = 10;
/**
* 内容区域的宽高.即单个水印范围的大小
*/
private int width = 200;
private int height = 200;
}
工具类
import org.apache.fontbox.ttf.TTFParser;
import org.apache.fontbox.ttf.TrueTypeCollection;
import org.apache.fontbox.ttf.TrueTypeFont;
import org.apache.fontbox.util.autodetect.FontFileFinder;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URI;
import java.net.URLEncoder;
public class PdfUtil {
private static final String DEFAULT_TTF_FILENAME = "simsun.ttf";
private static final String DEFAULT_TTC_FILENAME = "simsun.ttc";
private static final String DEFAULT_FONT_NAME = "SimSun";
private static final TrueTypeFont DEFAULT_FONT;
static {
DEFAULT_FONT = loadSystemFont();
}
/**
* 加载系统字体,提供默认字体
*
* @return
*/
private synchronized static TrueTypeFont loadSystemFont() {
//load 操作系统的默认字体. 宋体
FontFileFinder fontFileFinder = new FontFileFinder();
for (URI uri : fontFileFinder.find()) {
try {
final String filePath = uri.getPath();
if (filePath.endsWith(DEFAULT_TTF_FILENAME)) {
return new TTFParser(false).parse(filePath);
} else if (filePath.endsWith(DEFAULT_TTC_FILENAME)) {
TrueTypeCollection trueTypeCollection = new TrueTypeCollection(new FileInputStream(filePath));
final TrueTypeFont font = trueTypeCollection.getFontByName(DEFAULT_FONT_NAME);
//复制完之后关闭ttc
trueTypeCollection.close();
return font;
}
} catch (Exception e) {
throw new RuntimeException("加载操作系统字体失败", e);
}
}
return null;
}
/**
* 添加文本水印
* * 使用内嵌字体模式,pdf文件大小会增加1MB左右
*
* @param sourceFile 需要加水印的文件
* @param descFile 目标存储路径
* @param props 水印配置
* @throws IOException
*/
public static void addTextWatermark(File s