依赖包
使用itext7需要引入以下依赖包
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.8</version>
<type>pom</type>
</dependency>
处理水印方法一
生成水印
public void WatermarkPDF(String sourceFile, String destinationPath) throws IOException {
float watermarkTrimmingRectangleWidth = 300;
float watermarkTrimmingRectangleHeight = 300;
float formWidth = 300;
float formHeight = 300;
float formXOffset = 0;
float formYOffset = 0;
float xTranslation = 50;
float yTranslation = 25;
double rotationInRads = Math.PI/3;
PdfFont font = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
float fontSize = 50;
PdfDocument pdfDoc = new PdfDocument(new PdfReader(sourceFile), new PdfWriter(destinationPath));
int numberOfPages = pdfDoc.getNumberOfPages();
PdfPage page = null;
for (int i = 1; i <= numberOfPages; i++)
{
page = pdfDoc.getPage(i);
Rectangle ps = page.getPageSize();
//Center the annotation
float bottomLeftX = ps.getWidth()/2 - watermarkTrimmingRectangleWidth/2;
float bottomLeftY = ps.getHeight()/2 - watermarkTrimmingRectangleHeight/2;
Rectangle watermarkTrimmingRectangle = new Rectangle(bottomLeftX, bottomLeftY, watermarkTrimmingRectangleWidth, watermarkTrimmingRectangleHeight);
PdfWatermarkAnnotation watermark = new PdfWatermarkAnnotation(watermarkTrimmingRectangle);
//Apply linear algebra rotation math
//Create identity matrix
AffineTransform transform = new AffineTransform();//No-args constructor creates the identity transform
//Apply translation
transform.translate(xTranslation, yTranslation);
//Apply rotation
transform.rotate(rotationInRads);
PdfFixedPrint fixedPrint = new PdfFixedPrint();
watermark.setFixedPrint(fixedPrint);
//Create appearance
Rectangle formRectangle = new Rectangle(formXOffset, formYOffset, formWidth, formHeight);
//Observation: font XObject will be resized to fit inside the watermark rectangle
PdfFormXObject form = new PdfFormXObject(formRectangle);
PdfExtGState gs1 = new PdfExtGState().setFillOpacity(0.6f);
PdfCanvas canvas = new PdfCanvas(form, pdfDoc);
float[] transformValues = new float[6];
transform.getMatrix(transformValues);
canvas.saveState()
.beginText().setColor(ColorConstants.GRAY, true).setExtGState(gs1)
.setTextMatrix(transformValues[0], transformValues[1], transformValues[2], transformValues[3], transformValues[4], transformValues[5])
.setFontAndSize(font, fontSize)
.showText("watermark text")
.endText()
.restoreState();
canvas.release();
watermark.setAppearance(PdfName.N, new PdfAnnotationAppearance(form.getPdfObject()));
watermark.setFlags(PdfAnnotation.PRINT);
page.addAnnotation(watermark);
}
page.flush();
pdfDoc.close();
}
这种方法生成的水印不可编辑,不可复制
移除水印
在上述方法生成水印的前提下,可使用以下方法来移除水印
public void RemovetWatermarkPDF(String sourceFile, String destinationPath) throws IOException {
PdfDocument pdfDoc = new PdfDocument(new PdfReader(sourceFile), new PdfWriter(destinationPath));
int numberOfPages = pdfDoc.getNumberOfPages();
for (int i = 1; i <= numberOfPages; i++)
{
// PdfAnnotation
PdfDictionary pageDict = pdfDoc.getPage(i).getPdfObject();
PdfArray annots = pageDict.getAsArray(PdfName.Annots);
for (int j = 0; j < annots.size(); j++)
{
PdfDictionary annotation = annots.getAsDictionary(j);
if (PdfName.Watermark.equals(annotation.getAsName(PdfName.Subtype)))
{
annotation.clear();
}
}
}
pdfDoc.close();
}
这里添加移除的水印,和pdf正文不在同一层画布,因此可以进行移除操作。
方法二
我们也可以使用以下方法来生成水印
public void manipulatePdf(String dest) throws Exception {
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
Document doc = new Document(pdfDoc);
PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA);
Paragraph paragraph = new Paragraph("My")
.setFont(font)
.setFontSize(30);
ImageData img = ImageDataFactory.create(IMG);
float w = img.getWidth();
float h = img.getHeight();
PdfExtGState gs1 = new PdfExtGState().setFillOpacity(0.5f);
// Implement transformation matrix usage in order to scale image
for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
PdfPage pdfPage = pdfDoc.getPage(i);
Rectangle pageSize = pdfPage.getPageSizeWithRotation();
// When "true": in case the page has a rotation, then new content will be automatically rotated in the
// opposite direction. On the rotated page this would look as if new content ignores page rotation.
pdfPage.setIgnorePageRotationForContent(true);
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
// float y = (pageSize.getTop() + pageSize.getBottom()) / 2;
float y = pageSize.getTop() -70;
PdfCanvas over = new PdfCanvas(pdfDoc.getPage(i));
over.saveState();
over.setExtGState(gs1);
if (i % 2 == 1) {
doc.showTextAligned(paragraph, x, y, i, TextAlignment.CENTER, VerticalAlignment.TOP, 0);
} else {
over.addImageWithTransformationMatrix(img, w, 0, 0, h, x - (w / 2), y - (h / 2), false);
}
over.restoreState();
}
doc.close();
}
在Document中,有paragraph、div等元素,可用来在pdf画布上生成pdf要素。使用paragraph可以在pdf中创建一段文字,这里showTextAligned方法创建了div,效果类似paragraph。因此这种方法中生成的水印,等效于pdf正文,只是在样式以及透明度上做了区分。通过软件编辑pdf可发现这里的水印可被复制。
因为这里的水印和正文在同一图层中因此,不能被移除。