自适应文字长度水印
1.效果图
2.代码
2.1.pom
<!-- PDF文件依赖包 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.1</version>
</dependency>
<!-- PDF文件字体 防止中文乱码 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
2.2.水印工具类(自动调节文字个数)
import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import static com.shinkeer.common.utils.SecurityUtils.getUsername;
/**
* @program: 工具箱
* @description 水印
*/
public class PdfWatermarkUtil {
public static void main(String[] args) {
PdfWatermarkLocal("C:\\Users\\Pictures\\pdf水印测试.pdf", "C:\\Users\\Pictures\\pdf(加).pdf",
"一二三四五六七八九十十九八七六五四三二一");
}
public static void main2(String[] args) throws Exception {
File file = new File("C:\\Users\\Pictures\\pdf水印测试.pdf");
InputStream inputStream = file.toURL().openStream();
InputStream stream = PdfWatermarkTool.addPdfWatermark(inputStream, "这是水印" + DateUtil.now(), 10, 30, 50);
writeToLocal("C:\\Users\\Pictures\\AAA" + System.currentTimeMillis() + ".pdf", stream);
}
/**
* 将InputStream写入本地文件
*
* @param destination 写入本地目录
* @param input 输入流
* @throws IOException
*/
private static void writeToLocal(String destination, InputStream input) throws IOException {
int index;
byte[] bytes = new byte[1024];
FileOutputStream downloadFile = new FileOutputStream(destination);
while ((index = input.read(bytes)) != -1) {
downloadFile.write(bytes, 0, index);
downloadFile.flush();
}
downloadFile.close();
input.close();
}
/**
* 给PDF添加水印
* 修改为自适应文字长度水印
*
* @param inputFile 原文件路径+名称
* @param outputFile 添加水印后输出文件保存的路径+名称
* @param waterMarkName 添加水印的内容
*/
public static void PdfWatermarkLocal(String inputFile, String outputFile, String waterMarkName) {
try {
// 切记这里的参数是文件的路径 ,路径必须是双斜杠的如F:\\test.pdf,不能是F:/test.pdf 或者F:\test.pdf
PdfReader reader = new PdfReader(inputFile);
PdfStamper stamper = new PdfStamper(reader, Files.newOutputStream(Paths.get(outputFile)));
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.2f);//改透明度
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
label.setText(waterMarkName);
PdfContentByte under;
// 可添加多个水印
Rectangle pageRect = null;
label.setText(waterMarkName);
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
int width1 = (int) pageRect.getWidth();
int height1 = (int) pageRect.getHeight();
int fontSize = (width1 + height1) / 80;
// 间隔距离(参数可调节)
int interval = fontSize * 2;
// 文字占用的宽度
int xWidth = getStrWidth(waterMarkName, fontSize);
// x,y可以绘制的数量,多加一个补充空白
int xCanNum = width1 / xWidth + 1;
int yCanNum = height1 / fontSize + 1;
// 在内容上方加水印
under = stamper.getOverContent(i);
// 在内容下方加水印
//under = stamper.getUnderContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
//水印字体和大小
under.setFontAndSize(base, fontSize);
// 水印文字成30度角倾斜
for (int ii = 1; ii <= yCanNum; ii++) {
int y = fontSize * ii + interval * ii;
for (int jj = 0; jj < xCanNum; jj++) {
int x = xWidth * jj + interval * jj;
under.showTextAligned(Element.ALIGN_LEFT
, waterMarkName, x, y - (fontSize + interval) * jj, 30);
}
}
// 添加水印文字
under.endText();
}
stamper.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 给PDF添加水印
*
* @param inputStream 输入流
* @param waterMarkName 添加水印的内容
* @return OutputStream 输出流
*/
public static OutputStream PdfWatermarkOut(InputStream inputStream, String waterMarkName) {
try {
PdfReader reader = new PdfReader(inputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, outputStream);
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.2f);//改透明度
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
label.setText(waterMarkName);
PdfContentByte under;
// 可添加多个水印
Rectangle pageRect = null;
label.setText(waterMarkName);
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
int width1 = (int) pageRect.getWidth();
int height1 = (int) pageRect.getHeight();
int fontSize = (width1 + height1) / 80;
// 间隔距离(参数可调节)
int interval = fontSize * 2;
// 文字占用的宽度
int xWidth = getStrWidth(waterMarkName, fontSize);
// x,y可以绘制的数量,多加一个补充空白
int xCanNum = width1 / xWidth + 1;
int yCanNum = height1 / fontSize + 1;
// 在内容上方加水印
under = stamper.getOverContent(i);
// 在内容下方加水印
//under = stamper.getUnderContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
//水印字体和大小
under.setFontAndSize(base, fontSize);
// 水印文字成30度角倾斜
for (int ii = 1; ii <= yCanNum; ii++) {
int y = fontSize * ii + interval * ii;
for (int jj = 0; jj < xCanNum; jj++) {
int x = xWidth * jj + interval * jj;
under.showTextAligned(Element.ALIGN_LEFT
, waterMarkName, x, y - (fontSize + interval) * jj, 30);
}
}
// 添加水印文字
under.endText();
}
stamper.close();
reader.close();
return outputStream;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 给PDF添加水印
*
* @param inputStream 输入流
* @param waterMarkName 添加水印的内容
* @return OutputStream 输出流
*/
public static InputStream PdfWatermarkInt(InputStream inputStream, String waterMarkName) {
try {
PdfReader reader = new PdfReader(inputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, outputStream);
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.2f);//改透明度
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
label.setText(waterMarkName);
PdfContentByte under;
// 可添加多个水印
Rectangle pageRect = null;
label.setText(waterMarkName);
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
int width1 = (int) pageRect.getWidth();
int height1 = (int) pageRect.getHeight();
int fontSize = (width1 + height1) / 80;
// 间隔距离(参数可调节)
int interval = fontSize * 2;
// 文字占用的宽度
int xWidth = getStrWidth(waterMarkName, fontSize);
// x,y可以绘制的数量,多加一个补充空白
int xCanNum = width1 / xWidth + 1;
int yCanNum = height1 / fontSize + 1;
// 在内容上方加水印
under = stamper.getOverContent(i);
// 在内容下方加水印
//under = stamper.getUnderContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
//水印字体和大小
under.setFontAndSize(base, fontSize);
// 水印文字成30度角倾斜
for (int ii = 1; ii <= yCanNum; ii++) {
int y = fontSize * ii + interval * ii;
for (int jj = 0; jj < xCanNum; jj++) {
int x = xWidth * jj + interval * jj;
under.showTextAligned(Element.ALIGN_LEFT
, waterMarkName, x, y - (fontSize + interval) * jj, 30);
}
}
// 添加水印文字
under.endText();
}
stamper.close();
reader.close();
return new ByteArrayInputStream(outputStream.toByteArray());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取字符串占用的宽度
* <br>
*
* @param str 字符串
* @param fontSize 文字大小
* @return 字符串占用的宽度
*/
public static int getStrWidth(String str, int fontSize) {
char[] chars = str.toCharArray();
int fontSize2 = fontSize / 2;
int width = 0;
for (char c : chars) {
int len = String.valueOf(c).getBytes().length;
// 汉字为3,其余1
// 可能还有一些特殊字符占用2等等,统统计为汉字
if (len != 1) {
width += fontSize;
} else {
width += fontSize2;
}
}
return width == 0 ? 1 : width;
}
}
2.3.水印工具类(写死文字大小个数)
import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import static com.shinkeer.common.utils.SecurityUtils.getUsername;
/**
* @program: 工具箱
* @description 水印
* @date 2023/6/6
*/
public class PdfWatermarkUtil {
public static void main(String[] args) {
PdfWatermarkLocal("D:\\AAA.pdf", "D:\\BBB.pdf", "这是水印");
}
public static void main2(String[] args) throws Exception {
File file = new File("D:\\AAA.pdf");
InputStream inputStream = file.toURL().openStream();
InputStream stream = PdfWatermarkTool.addPdfWatermark(inputStream, "这是水印" + DateUtil.now(), 10, 30, 50);
writeToLocal("D:\\AAA" + System.currentTimeMillis() + ".pdf", stream);
}
/**
* 将InputStream写入本地文件
*
* @param destination 写入本地目录
* @param input 输入流
* @throws IOException
*/
private static void writeToLocal(String destination, InputStream input) throws IOException {
int index;
byte[] bytes = new byte[1024];
FileOutputStream downloadFile = new FileOutputStream(destination);
while ((index = input.read(bytes)) != -1) {
downloadFile.write(bytes, 0, index);
downloadFile.flush();
}
downloadFile.close();
input.close();
}
/**
* 给PDF添加水印
*
* @param inputFile 原文件路径+名称
* @param outputFile 添加水印后输出文件保存的路径+名称
* @param waterMarkName 添加水印的内容
*/
public static void PdfWatermarkLocal(String inputFile, String outputFile, String waterMarkName) {
try {
// 水印的高和宽(参数可调节)
int textH = 75;
int textW = 170;
// 间隔距离(参数可调节)
int interval = 30;
// 切记这里的参数是文件的路径 ,路径必须是双斜杠的如F:\\test.pdf,不能是F:/test.pdf 或者F:\test.pdf
PdfReader reader = new PdfReader(inputFile);
PdfStamper stamper = new PdfStamper(reader, Files.newOutputStream(Paths.get(outputFile)));
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.2f);//改透明度
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
label.setText(waterMarkName);
PdfContentByte under;
// 可添加多个水印
Rectangle pageRect = null;
FontMetrics metrics;
label.setText(waterMarkName);
metrics = label.getFontMetrics(label.getFont());
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
// 在内容上方加水印
under = stamper.getOverContent(i);
// 在内容下方加水印
//under = stamper.getUnderContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
under.setFontAndSize(base, 20);
// 水印文字成30度角倾斜
for (int height = interval + textH; height < pageRect.getHeight();
height = height + textH * 3) {
for (int width = interval + textW; width < pageRect.getWidth() + textW;
width = width + textW * 2) {
under.showTextAligned(Element.ALIGN_LEFT
, waterMarkName, width - textW,
height - textH, 30);
}
}
// 添加水印文字
under.endText();
}
stamper.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 给PDF添加水印
*
* @param inputStream 输入流
* @param waterMarkName 添加水印的内容
* @return OutputStream 输出流
*/
public static OutputStream PdfWatermarkOut(InputStream inputStream, String waterMarkName) {
try {
// 水印的高和宽(参数可调节)
int textH = 75;
int textW = 170;
// 间隔距离(参数可调节)
int interval = 30;
PdfReader reader = new PdfReader(inputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, outputStream);
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.2f);//改透明度
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
label.setText(waterMarkName);
PdfContentByte under;
// 可添加多个水印
Rectangle pageRect = null;
FontMetrics metrics;
label.setText(waterMarkName);
metrics = label.getFontMetrics(label.getFont());
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
// 在内容上方加水印
under = stamper.getOverContent(i);
// 在内容下方加水印
//under = stamper.getUnderContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
under.setFontAndSize(base, 20);
// 水印文字成30度角倾斜
for (int height = interval + textH; height < pageRect.getHeight();
height = height + textH * 3) {
for (int width = interval + textW; width < pageRect.getWidth() + textW;
width = width + textW * 2) {
under.showTextAligned(Element.ALIGN_LEFT
, waterMarkName, width - textW,
height - textH, 30);
}
}
// 添加水印文字
under.endText();
}
stamper.close();
reader.close();
return outputStream;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 给PDF添加水印
*
* @param inputStream 输入流
* @param waterMarkName 添加水印的内容
* @return OutputStream 输出流
*/
public static InputStream PdfWatermarkInt(InputStream inputStream, String waterMarkName) {
try {
// 水印的高和宽(参数可调节)
int textH = 75;
int textW = 170;
// 间隔距离(参数可调节)
int interval = 30;
PdfReader reader = new PdfReader(inputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, outputStream);
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.2f);//改透明度
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
label.setText(waterMarkName);
PdfContentByte under;
// 可添加多个水印
Rectangle pageRect = null;
FontMetrics metrics;
label.setText(waterMarkName);
metrics = label.getFontMetrics(label.getFont());
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
// 在内容上方加水印
under = stamper.getOverContent(i);
// 在内容下方加水印
//under = stamper.getUnderContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
under.setFontAndSize(base, 20);
// 水印文字成30度角倾斜
for (int height = interval + textH; height < pageRect.getHeight();
height = height + textH * 3) {
for (int width = interval + textW; width < pageRect.getWidth() + textW;
width = width + textW * 2) {
under.showTextAligned(Element.ALIGN_LEFT
, waterMarkName, width - textW,
height - textH, 30);
}
}
// 添加水印文字
under.endText();
}
stamper.close();
reader.close();
return new ByteArrayInputStream(outputStream.toByteArray());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192732.html